forked from Telodendria/Cytoplasm
Compare commits
2 commits
346b912a06
...
007b8f6d43
Author | SHA1 | Date | |
---|---|---|---|
007b8f6d43 | |||
9108fef701 |
2 changed files with 86 additions and 148 deletions
35
src/Db.c
35
src/Db.c
|
@ -218,19 +218,38 @@ DbHashKey(Array * args)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char
|
||||||
|
DbSanitiseChar(char input)
|
||||||
|
{
|
||||||
|
switch (input)
|
||||||
|
{
|
||||||
|
case '/':
|
||||||
|
return '_';
|
||||||
|
case '.':
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
DbDirName(Db * db, Array * args, size_t strip)
|
DbDirName(Db * db, Array * args, size_t strip)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i, j;
|
||||||
char *str = StrConcat(2, db->dir, "/");
|
char *str = StrConcat(2, db->dir, "/");
|
||||||
|
|
||||||
for (i = 0; i < ArraySize(args) - strip; i++)
|
for (i = 0; i < ArraySize(args) - strip; i++)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
char *sanitise = StrDuplicate(ArrayGet(args, i));
|
||||||
|
for (j = 0; j < strlen(sanitise); j++)
|
||||||
|
{
|
||||||
|
sanitise[j] = DbSanitiseChar(sanitise[j]);
|
||||||
|
}
|
||||||
|
|
||||||
tmp = StrConcat(3, str, ArrayGet(args, i), "/");
|
tmp = StrConcat(3, str, sanitise, "/");
|
||||||
|
|
||||||
Free(str);
|
Free(str);
|
||||||
|
Free(sanitise);
|
||||||
|
|
||||||
str = tmp;
|
str = tmp;
|
||||||
}
|
}
|
||||||
|
@ -253,17 +272,7 @@ DbFileName(Db * db, Array * args)
|
||||||
/* Sanitize name to prevent directory traversal attacks */
|
/* Sanitize name to prevent directory traversal attacks */
|
||||||
while (arg[j])
|
while (arg[j])
|
||||||
{
|
{
|
||||||
switch (arg[j])
|
arg[j] = DbSanitiseChar(arg[j]);
|
||||||
{
|
|
||||||
case '/':
|
|
||||||
arg[j] = '_';
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
arg[j] = '-';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
189
src/Memory.c
189
src/Memory.c
|
@ -42,14 +42,20 @@
|
||||||
|
|
||||||
struct MemoryInfo
|
struct MemoryInfo
|
||||||
{
|
{
|
||||||
|
uint64_t magic;
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
const char *file;
|
const char *file;
|
||||||
int line;
|
int line;
|
||||||
void *pointer;
|
void *pointer;
|
||||||
|
|
||||||
|
MemoryInfo *prev;
|
||||||
|
MemoryInfo *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MEM_BOUND_TYPE uint32_t
|
#define MEM_BOUND_TYPE uint32_t
|
||||||
#define MEM_BOUND 0xDEADBEEF
|
#define MEM_BOUND 0xDEADBEEF
|
||||||
|
#define MEM_MAGIC 0x4E69746F72697961
|
||||||
|
|
||||||
#define MEM_BOUND_LOWER(p) *((MEM_BOUND_TYPE *) p)
|
#define MEM_BOUND_LOWER(p) *((MEM_BOUND_TYPE *) p)
|
||||||
#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((uint8_t *) p) + x)) + 1)
|
#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((uint8_t *) p) + x)) + 1)
|
||||||
|
@ -59,10 +65,10 @@ static pthread_mutex_t lock;
|
||||||
static void (*hook) (MemoryAction, MemoryInfo *, void *) = MemoryDefaultHook;
|
static void (*hook) (MemoryAction, MemoryInfo *, void *) = MemoryDefaultHook;
|
||||||
static void *hookArgs = NULL;
|
static void *hookArgs = NULL;
|
||||||
|
|
||||||
static MemoryInfo **allocations = NULL;
|
|
||||||
static size_t allocationsSize = 0;
|
|
||||||
static size_t allocationsLen = 0;
|
static size_t allocationsLen = 0;
|
||||||
|
|
||||||
|
static MemoryInfo *allocationTail = NULL;
|
||||||
|
|
||||||
int
|
int
|
||||||
MemoryRuntimeInit(void)
|
MemoryRuntimeInit(void)
|
||||||
{
|
{
|
||||||
|
@ -91,70 +97,18 @@ MemoryRuntimeDestroy(void)
|
||||||
return pthread_mutex_destroy(&lock) == 0;
|
return pthread_mutex_destroy(&lock) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
|
||||||
MemoryHash(void *p)
|
|
||||||
{
|
|
||||||
return (((size_t) p) >> 2 * 7) % allocationsSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
MemoryInsert(MemoryInfo * a)
|
MemoryInsert(MemoryInfo * a)
|
||||||
{
|
{
|
||||||
size_t hash;
|
if (allocationTail)
|
||||||
|
|
||||||
if (!allocations)
|
|
||||||
{
|
{
|
||||||
allocationsSize = MEMORY_TABLE_CHUNK;
|
allocationTail->next = a;
|
||||||
allocations = calloc(allocationsSize, sizeof(void *));
|
|
||||||
if (!allocations)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
a->next = NULL;
|
||||||
|
a->prev = allocationTail;
|
||||||
|
a->magic = MEM_MAGIC;
|
||||||
|
|
||||||
/* If the next insertion would cause the table to be at least 3/4
|
allocationTail = a;
|
||||||
* full, re-allocate and re-hash. */
|
|
||||||
if ((allocationsLen + 1) >= ((allocationsSize * 3) >> 2))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t tmpAllocationsSize = allocationsSize;
|
|
||||||
MemoryInfo **tmpAllocations;
|
|
||||||
|
|
||||||
allocationsSize += MEMORY_TABLE_CHUNK;
|
|
||||||
tmpAllocations = calloc(allocationsSize, sizeof(void *));
|
|
||||||
|
|
||||||
if (!tmpAllocations)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < tmpAllocationsSize; i++)
|
|
||||||
{
|
|
||||||
if (allocations[i])
|
|
||||||
{
|
|
||||||
hash = MemoryHash(allocations[i]->pointer);
|
|
||||||
|
|
||||||
while (tmpAllocations[hash])
|
|
||||||
{
|
|
||||||
hash = (hash + 1) % allocationsSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpAllocations[hash] = allocations[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(allocations);
|
|
||||||
allocations = tmpAllocations;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash = MemoryHash(a->pointer);
|
|
||||||
|
|
||||||
while (allocations[hash])
|
|
||||||
{
|
|
||||||
hash = (hash + 1) % allocationsSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocations[hash] = a;
|
|
||||||
allocationsLen++;
|
allocationsLen++;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -163,23 +117,24 @@ MemoryInsert(MemoryInfo * a)
|
||||||
static void
|
static void
|
||||||
MemoryDelete(MemoryInfo * a)
|
MemoryDelete(MemoryInfo * a)
|
||||||
{
|
{
|
||||||
size_t hash = MemoryHash(a->pointer);
|
MemoryInfo *aPrev = a->prev;
|
||||||
size_t count = 0;
|
MemoryInfo *aNext = a->next;
|
||||||
|
|
||||||
while (count <= allocationsSize)
|
if (aPrev)
|
||||||
{
|
{
|
||||||
if (allocations[hash] && allocations[hash] == a)
|
aPrev->next = aNext;
|
||||||
|
}
|
||||||
|
if (aNext)
|
||||||
{
|
{
|
||||||
allocations[hash] = NULL;
|
aNext->prev = aPrev;
|
||||||
allocationsLen--;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (a == allocationTail)
|
||||||
{
|
{
|
||||||
hash = (hash + 1) % allocationsSize;
|
allocationTail = aPrev;
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a->magic = ~MEM_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -203,24 +158,18 @@ MemoryAllocate(size_t size, const char *file, int line)
|
||||||
void *p;
|
void *p;
|
||||||
MemoryInfo *a;
|
MemoryInfo *a;
|
||||||
|
|
||||||
MemoryIterate(NULL, NULL);
|
//MemoryIterate(NULL, NULL);
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
a = malloc(sizeof(MemoryInfo));
|
a = malloc(sizeof(MemoryInfo) + MEM_SIZE_ACTUAL(size));
|
||||||
if (!a)
|
if (!a)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = malloc(MEM_SIZE_ACTUAL(size));
|
p = a + 1;
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
free(a);
|
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(p, 0, MEM_SIZE_ACTUAL(size));
|
memset(p, 0, MEM_SIZE_ACTUAL(size));
|
||||||
MEM_BOUND_LOWER(p) = MEM_BOUND;
|
MEM_BOUND_LOWER(p) = MEM_BOUND;
|
||||||
|
@ -234,7 +183,6 @@ MemoryAllocate(size_t size, const char *file, int line)
|
||||||
if (!MemoryInsert(a))
|
if (!MemoryInsert(a))
|
||||||
{
|
{
|
||||||
free(a);
|
free(a);
|
||||||
free(p);
|
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +202,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
|
||||||
MemoryInfo *a;
|
MemoryInfo *a;
|
||||||
void *new = NULL;
|
void *new = NULL;
|
||||||
|
|
||||||
MemoryIterate(NULL, NULL);
|
//MemoryIterate(NULL, NULL);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
|
@ -265,15 +213,17 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
new = realloc(a->pointer, MEM_SIZE_ACTUAL(size));
|
MemoryDelete(a);
|
||||||
|
new = realloc(a, sizeof(MemoryInfo) + MEM_SIZE_ACTUAL(size));
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
MemoryDelete(a);
|
a = new;
|
||||||
a->size = MEM_SIZE_ACTUAL(size);
|
a->size = MEM_SIZE_ACTUAL(size);
|
||||||
a->file = file;
|
a->file = file;
|
||||||
a->line = line;
|
a->line = line;
|
||||||
|
a->magic = MEM_MAGIC;
|
||||||
|
|
||||||
a->pointer = new;
|
a->pointer = a + 1;
|
||||||
MemoryInsert(a);
|
MemoryInsert(a);
|
||||||
|
|
||||||
MEM_BOUND_LOWER(a->pointer) = MEM_BOUND;
|
MEM_BOUND_LOWER(a->pointer) = MEM_BOUND;
|
||||||
|
@ -301,7 +251,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((MEM_BOUND_TYPE *) new) + 1;
|
return ((MEM_BOUND_TYPE *) a->pointer) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -309,7 +259,7 @@ MemoryFree(void *p, const char *file, int line)
|
||||||
{
|
{
|
||||||
MemoryInfo *a;
|
MemoryInfo *a;
|
||||||
|
|
||||||
MemoryIterate(NULL, NULL);
|
//MemoryIterate(NULL, NULL);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
|
@ -327,7 +277,6 @@ MemoryFree(void *p, const char *file, int line)
|
||||||
hook(MEMORY_FREE, a, hookArgs);
|
hook(MEMORY_FREE, a, hookArgs);
|
||||||
}
|
}
|
||||||
MemoryDelete(a);
|
MemoryDelete(a);
|
||||||
free(a->pointer);
|
|
||||||
free(a);
|
free(a);
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
|
@ -350,17 +299,15 @@ MemoryFree(void *p, const char *file, int line)
|
||||||
size_t
|
size_t
|
||||||
MemoryAllocated(void)
|
MemoryAllocated(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
MemoryInfo *cur;
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
for (i = 0; i < allocationsSize; i++)
|
/* TODO */
|
||||||
|
for (cur = allocationTail; cur; cur = cur->prev)
|
||||||
{
|
{
|
||||||
if (allocations[i])
|
total += MemoryInfoGetSize(cur);
|
||||||
{
|
|
||||||
total += MemoryInfoGetSize(allocations[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
|
@ -371,55 +318,40 @@ MemoryAllocated(void)
|
||||||
void
|
void
|
||||||
MemoryFreeAll(void)
|
MemoryFreeAll(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
MemoryInfo *cur;
|
||||||
|
MemoryInfo *prev;
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
for (i = 0; i < allocationsSize; i++)
|
/* TODO */
|
||||||
|
for (cur = allocationTail; cur; cur = prev)
|
||||||
{
|
{
|
||||||
if (allocations[i])
|
prev = cur->prev;
|
||||||
{
|
free(cur);
|
||||||
free(allocations[i]->pointer);
|
|
||||||
free(allocations[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(allocations);
|
|
||||||
allocations = NULL;
|
|
||||||
allocationsSize = 0;
|
|
||||||
allocationsLen = 0;
|
allocationsLen = 0;
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryInfo *
|
MemoryInfo *
|
||||||
MemoryInfoGet(void *p)
|
MemoryInfoGet(void *po)
|
||||||
{
|
{
|
||||||
size_t hash, count;
|
void *p = po;
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
p = ((MEM_BOUND_TYPE *) p) - 1;
|
p = ((MEM_BOUND_TYPE *) po) - 1;
|
||||||
hash = MemoryHash(p);
|
p = ((MemoryInfo *) p) - 1;
|
||||||
|
|
||||||
count = 0;
|
if (((MemoryInfo *)p)->magic != MEM_MAGIC)
|
||||||
while (count <= allocationsSize)
|
|
||||||
{
|
{
|
||||||
if (!allocations[hash] || allocations[hash]->pointer != p)
|
p = NULL;
|
||||||
{
|
|
||||||
hash = (hash + 1) % allocationsSize;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MemoryCheck(allocations[hash]);
|
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
return allocations[hash];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return NULL;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
@ -467,21 +399,18 @@ MemoryInfoGetPointer(MemoryInfo * a)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MemoryIterate(void (*iterFunc) (MemoryInfo *, void *), void *args)
|
MemoryIterate(void (*iterFunc) (MemoryInfo *, void *), void *args)
|
||||||
{
|
{
|
||||||
size_t i;
|
MemoryInfo *cur;
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
for (i = 0; i < allocationsSize; i++)
|
for (cur = allocationTail; cur; cur = cur->prev)
|
||||||
{
|
{
|
||||||
if (allocations[i])
|
MemoryCheck(cur);
|
||||||
{
|
|
||||||
MemoryCheck(allocations[i]);
|
|
||||||
if (iterFunc)
|
if (iterFunc)
|
||||||
{
|
{
|
||||||
iterFunc(allocations[i], args);
|
iterFunc(cur, args);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue