Compare commits

..

No commits in common. "007b8f6d43ecc35cd4ec8777c117ab3659a38305" and "346b912a0633cceac10780b8a103f6c89b5ba89f" have entirely different histories.

2 changed files with 150 additions and 88 deletions

View file

@ -218,38 +218,19 @@ 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, j; size_t i;
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, sanitise, "/"); tmp = StrConcat(3, str, ArrayGet(args, i), "/");
Free(str); Free(str);
Free(sanitise);
str = tmp; str = tmp;
} }
@ -272,7 +253,17 @@ 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])
{ {
arg[j] = DbSanitiseChar(arg[j]); switch (arg[j])
{
case '/':
arg[j] = '_';
break;
case '.':
arg[j] = '-';
break;
default:
break;
}
j++; j++;
} }

View file

@ -42,20 +42,14 @@
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)
@ -65,10 +59,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)
{ {
@ -97,18 +91,70 @@ 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)
{ {
if (allocationTail) size_t hash;
{
allocationTail->next = a;
}
a->next = NULL;
a->prev = allocationTail;
a->magic = MEM_MAGIC;
allocationTail = a; if (!allocations)
{
allocationsSize = MEMORY_TABLE_CHUNK;
allocations = calloc(allocationsSize, sizeof(void *));
if (!allocations)
{
return 0;
}
}
/* If the next insertion would cause the table to be at least 3/4
* 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;
@ -117,24 +163,23 @@ MemoryInsert(MemoryInfo * a)
static void static void
MemoryDelete(MemoryInfo * a) MemoryDelete(MemoryInfo * a)
{ {
MemoryInfo *aPrev = a->prev; size_t hash = MemoryHash(a->pointer);
MemoryInfo *aNext = a->next; size_t count = 0;
if (aPrev) while (count <= allocationsSize)
{ {
aPrev->next = aNext; if (allocations[hash] && allocations[hash] == a)
}
if (aNext)
{ {
aNext->prev = aPrev; allocations[hash] = NULL;
allocationsLen--;
return;
} }
else
if (a == allocationTail)
{ {
allocationTail = aPrev; hash = (hash + 1) % allocationsSize;
count++;
}
} }
a->magic = ~MEM_MAGIC;
} }
static int static int
@ -158,18 +203,24 @@ 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) + MEM_SIZE_ACTUAL(size)); a = malloc(sizeof(MemoryInfo));
if (!a) if (!a)
{ {
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
return NULL; return NULL;
} }
p = a + 1; p = malloc(MEM_SIZE_ACTUAL(size));
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;
@ -183,6 +234,7 @@ 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;
} }
@ -202,7 +254,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)
{ {
@ -213,17 +265,15 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
if (a) if (a)
{ {
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
MemoryDelete(a); new = realloc(a->pointer, MEM_SIZE_ACTUAL(size));
new = realloc(a, sizeof(MemoryInfo) + MEM_SIZE_ACTUAL(size));
if (new) if (new)
{ {
a = new; MemoryDelete(a);
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 = a + 1; a->pointer = new;
MemoryInsert(a); MemoryInsert(a);
MEM_BOUND_LOWER(a->pointer) = MEM_BOUND; MEM_BOUND_LOWER(a->pointer) = MEM_BOUND;
@ -251,7 +301,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
} }
} }
return ((MEM_BOUND_TYPE *) a->pointer) + 1; return ((MEM_BOUND_TYPE *) new) + 1;
} }
void void
@ -259,7 +309,7 @@ MemoryFree(void *p, const char *file, int line)
{ {
MemoryInfo *a; MemoryInfo *a;
//MemoryIterate(NULL, NULL); MemoryIterate(NULL, NULL);
if (!p) if (!p)
{ {
@ -277,6 +327,7 @@ 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);
@ -299,15 +350,17 @@ 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);
/* TODO */ for (i = 0; i < allocationsSize; i++)
for (cur = allocationTail; cur; cur = cur->prev)
{ {
total += MemoryInfoGetSize(cur); if (allocations[i])
{
total += MemoryInfoGetSize(allocations[i]);
}
} }
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
@ -318,40 +371,55 @@ MemoryAllocated(void)
void void
MemoryFreeAll(void) MemoryFreeAll(void)
{ {
MemoryInfo *cur; size_t i;
MemoryInfo *prev;
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
/* TODO */ for (i = 0; i < allocationsSize; i++)
for (cur = allocationTail; cur; cur = prev)
{ {
prev = cur->prev; if (allocations[i])
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 *po) MemoryInfoGet(void *p)
{ {
void *p = po; size_t hash, count;
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
p = ((MEM_BOUND_TYPE *) po) - 1; p = ((MEM_BOUND_TYPE *) p) - 1;
p = ((MemoryInfo *) p) - 1; hash = MemoryHash(p);
if (((MemoryInfo *)p)->magic != MEM_MAGIC) count = 0;
while (count <= allocationsSize)
{ {
p = NULL; if (!allocations[hash] || allocations[hash]->pointer != p)
{
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 p; return NULL;
} }
size_t size_t
@ -399,18 +467,21 @@ MemoryInfoGetPointer(MemoryInfo * a)
} }
void void
MemoryIterate(void (*iterFunc) (MemoryInfo *, void *), void *args) MemoryIterate(void (*iterFunc) (MemoryInfo *, void *), void *args)
{ {
MemoryInfo *cur; size_t i;
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
for (cur = allocationTail; cur; cur = cur->prev) for (i = 0; i < allocationsSize; i++)
{ {
MemoryCheck(cur); if (allocations[i])
{
MemoryCheck(allocations[i]);
if (iterFunc) if (iterFunc)
{ {
iterFunc(cur, args); iterFunc(allocations[i], args);
}
} }
} }