From ebe74fd253bdda11227f493efc7e919f502ea533 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 3 Aug 2022 15:24:05 -0700 Subject: [PATCH] cache: free the cache table when it is empty and set to NULL We do the latter for the benefit of libpkgconf. This cleans up a significant number of memory leaks in the cache handling. --- libpkgconf/cache.c | 27 +++++++++++++++++++++++++-- libpkgconf/client.c | 2 ++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/libpkgconf/cache.c b/libpkgconf/cache.c index 90e73cb..665769f 100644 --- a/libpkgconf/cache.c +++ b/libpkgconf/cache.c @@ -16,6 +16,8 @@ #include #include +#include + /* * !doc * @@ -86,6 +88,9 @@ cache_dump(const pkgconf_client_t *client) pkgconf_pkg_t * pkgconf_cache_lookup(pkgconf_client_t *client, const char *id) { + if (client->cache_table == NULL) + return NULL; + pkgconf_pkg_t **pkg; pkg = bsearch(id, client->cache_table, @@ -150,6 +155,9 @@ pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg) void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg) { + if (client->cache_table == NULL) + return; + if (pkg == NULL) return; @@ -181,8 +189,16 @@ pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg) } client->cache_count--; - client->cache_table = pkgconf_reallocarray(client->cache_table, - client->cache_count, sizeof(void *)); + if (client->cache_count > 0) + { + client->cache_table = pkgconf_reallocarray(client->cache_table, + client->cache_count, sizeof(void *)); + } + else + { + free(client->cache_table); + client->cache_table = NULL; + } } static inline void @@ -211,6 +227,9 @@ clear_dependency_matches(pkgconf_list_t *list) void pkgconf_cache_free(pkgconf_client_t *client) { + if (client->cache_table == NULL) + return; + pkgconf_pkg_t **cache_table; size_t i, count; @@ -235,6 +254,10 @@ pkgconf_cache_free(pkgconf_client_t *client) pkgconf_pkg_t *pkg = cache_table[i]; pkgconf_pkg_free(client, pkg); } + free(cache_table); + free(client->cache_table); + client->cache_table = NULL; + client->cache_count = 0; PKGCONF_TRACE(client, "cleared package cache"); } diff --git a/libpkgconf/client.c b/libpkgconf/client.c index 05f24ec..6502ff4 100644 --- a/libpkgconf/client.c +++ b/libpkgconf/client.c @@ -98,6 +98,8 @@ pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error client->error_handler_data = error_handler_data; client->error_handler = error_handler; client->auditf = NULL; + client->cache_table = NULL; + client->cache_count = 0; #ifndef PKGCONF_LITE if (client->trace_handler == NULL)