From e757f736e7f363f1fd03cb6b198f96888d31ad18 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 29 Oct 2016 21:31:18 +0100 Subject: [PATCH] _ostree_kernel_args_replace_take: don't leak when replacing If !existed, then we add arg to kargs->order, where it will be freed by that array's free-function. However, if the kernel argument did already exist, we have to either free arg ourselves (and make sure the old key is what appears in the hash table), or do a linear search on kargs->order to replace the old key with the new. Leak found by valgrind memcheck. Signed-off-by: Simon McVittie Closes: #559 Approved by: cgwalters --- src/libostree/ostree-kernel-args.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/libostree/ostree-kernel-args.c b/src/libostree/ostree-kernel-args.c index 4c9ff147..ec189fc1 100644 --- a/src/libostree/ostree-kernel-args.c +++ b/src/libostree/ostree-kernel-args.c @@ -87,12 +87,21 @@ _ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, gboolean existed; GPtrArray *values = g_ptr_array_new_with_free_func (g_free); const char *value = split_keyeq (arg); + gpointer old_key; - existed = g_hash_table_remove (kargs->table, arg); - if (!existed) - g_ptr_array_add (kargs->order, arg); g_ptr_array_add (values, g_strdup (value)); - g_hash_table_replace (kargs->table, arg, values); + existed = g_hash_table_lookup_extended (kargs->table, arg, &old_key, NULL); + + if (existed) + { + g_hash_table_replace (kargs->table, old_key, values); + g_free (arg); + } + else + { + g_ptr_array_add (kargs->order, arg); + g_hash_table_replace (kargs->table, arg, values); + } } void