diff --git a/TODO.txt b/TODO.txt index dc35c33..1093de1 100644 --- a/TODO.txt +++ b/TODO.txt @@ -11,11 +11,6 @@ Key: Milestone: v0.1.1 ----------------- -[x] DbDelete() -[x] UtilRandomString() -[x] Hex dump leaked memory -[ ] Leaks in DB - [ ] Database version file [ ] User registration diff --git a/man/man7/telodendria-changelog.7 b/man/man7/telodendria-changelog.7 index 48504a6..e39f70a 100644 --- a/man/man7/telodendria-changelog.7 +++ b/man/man7/telodendria-changelog.7 @@ -82,6 +82,9 @@ parser that prevented GET parameters from being parsed. Fixed the database file name generator to prevent directory traversal attacks by replacing special characters with safer ones. +.It +Fixed a memory leak that would occur when closing a +database that contains cached objects. .El .Pp Misc: diff --git a/src/Db.c b/src/Db.c index 054ad97..d49fe2b 100644 --- a/src/Db.c +++ b/src/Db.c @@ -60,6 +60,19 @@ struct DbRef FILE *fp; }; +static void +StringArrayFree(Array *arr) +{ + size_t i; + + for (i = 0; i < ArraySize(arr); i++) + { + Free(ArrayGet(arr, i)); + } + + ArrayFree(arr); +} + static ssize_t DbComputeSize(HashMap *); static ssize_t @@ -209,22 +222,23 @@ DbFileName(Db * db, Array * args) { char *tmp, *tmp2; char *arg = UtilStringDuplicate(ArrayGet(args, i)); + size_t j = 0; /* Sanitize name to prevent directory traversal attacks */ - while (*arg) + while (arg[j]) { - switch (*arg) + switch (arg[j]) { case '/': - *arg = '_'; + arg[j] = '_'; break; case '.': - *arg = '-'; + arg[j] = '-'; break; default: break; } - arg++; + j++; } tmp = UtilStringConcat(str, arg); @@ -266,7 +280,7 @@ DbCacheEvict(Db * db) HashMapDelete(db->cache, hash); Free(hash); - ArrayFree(ref->name); + StringArrayFree(ref->name); db->cacheSize -= ref->size; @@ -337,7 +351,7 @@ DbClose(Db * db) { Free(key); JsonFree(val->json); - ArrayFree(val->name); + StringArrayFree(val->name); pthread_mutex_destroy(&val->lock); Free(val); } @@ -507,6 +521,7 @@ DbCreate(Db * db, size_t nArgs,...) char *dir; va_list ap; Array *args; + DbRef *ret; if (!db) { @@ -554,7 +569,11 @@ DbCreate(Db * db, size_t nArgs,...) fflush(fp); fclose(fp); - return DbLockFromArr(db, args); + ret = DbLockFromArr(db, args); + + ArrayFree(args); + + return ret; } int @@ -588,7 +607,7 @@ DbDelete(Db * db, size_t nArgs,...) HashMapDelete(db->cache, hash); JsonFree(ref->json); - ArrayFree(ref->name); + StringArrayFree(ref->name); db->cacheSize -= ref->size;