From: Reuben Thomas Date: Fri, 26 Jan 2018 12:11:33 +0000 (+0000) Subject: Fix a potential memory leak in declare_single X-Git-Tag: v3.7~51 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb1b3a44f44d2fb94b9a9cf2c9e9c0eb702b8e9d;p=recode Fix a potential memory leak in declare_single --- diff --git a/src/names.c b/src/names.c index 5d47c51..46f7b21 100644 --- a/src/names.c +++ b/src/names.c @@ -243,6 +243,17 @@ disambiguate_name (RECODE_OUTER outer, return result; } +/*----------------------------------------------------------------------------. +| Delete the given alias. | +`----------------------------------------------------------------------------*/ + +void +delete_alias (RECODE_ALIAS alias) +{ + free (alias->symbol); + free (alias); +} + /*----------------------------------------------------------------------------. | Return the alias from its given NAME, possibly abbreviated. If FIND_TYPE | | is any of SYMBOL_CREATE_*, NAME is not abbreviated, create a new symbol if | @@ -317,8 +328,7 @@ find_alias (RECODE_OUTER outer, const char *name, alias->implied_surfaces = NULL; if (!hash_insert ((Hash_table *) outer->alias_table, alias)) { - free (symbol); - free (alias); + delete_alias (alias); return NULL; } diff --git a/src/outer.c b/src/outer.c index c8f5745..c1134ae 100644 --- a/src/outer.c +++ b/src/outer.c @@ -68,6 +68,7 @@ declare_single (RECODE_OUTER outer, Recode_init init_routine, Recode_transform transform_routine) { RECODE_SINGLE single = new_single_step (outer); + RECODE_ALIAS before = NULL, after = NULL; if (!single) return NULL; @@ -75,44 +76,45 @@ declare_single (RECODE_OUTER outer, if (strcmp (before_name, "data") == 0) { single->before = outer->data_symbol; - single->after = find_alias (outer, after_name, - SYMBOL_CREATE_DATA_SURFACE)->symbol; + after = find_alias (outer, after_name, SYMBOL_CREATE_DATA_SURFACE); + single->after = after->symbol; } else if (strcmp(after_name, "data") == 0) { - single->before = find_alias (outer, before_name, - SYMBOL_CREATE_DATA_SURFACE)->symbol; + before = find_alias (outer, before_name, SYMBOL_CREATE_DATA_SURFACE); + single->before = before->symbol; single->after = outer->data_symbol; } else if (strcmp (before_name, "tree") == 0) { single->before = outer->tree_symbol; - single->after = find_alias (outer, after_name, - SYMBOL_CREATE_TREE_SURFACE)->symbol; + after = find_alias (outer, after_name, SYMBOL_CREATE_TREE_SURFACE); + single->after = after->symbol; } else if (strcmp(after_name, "tree") == 0) { - single->before = find_alias (outer, before_name, - SYMBOL_CREATE_TREE_SURFACE)->symbol; + before = find_alias (outer, before_name, SYMBOL_CREATE_TREE_SURFACE); + single->before = before->symbol; single->after = outer->tree_symbol; } else { - single->before = find_alias (outer, before_name, - SYMBOL_CREATE_CHARSET)->symbol; - single->after = find_alias (outer, after_name, - SYMBOL_CREATE_CHARSET)->symbol; + before = find_alias (outer, before_name, SYMBOL_CREATE_CHARSET); + single->before = before->symbol; + after = find_alias (outer, after_name, SYMBOL_CREATE_CHARSET); + single->after = after->symbol; } -#if 0 - /* FIXME: We should delink from the list of charsets before freeing. - The alias should also be freed. */ - if (!before || !after) + if (!single->before || !single->after) { - free (single->before); + if (before) + delete_alias (before); + if (after) + delete_alias (after); + outer->single_list = single->next; + free (single); return NULL; } -#endif single->quality = quality; single->init_routine = init_routine; diff --git a/src/recodext.h b/src/recodext.h index aad1340..5d37130 100644 --- a/src/recodext.h +++ b/src/recodext.h @@ -602,6 +602,7 @@ RECODE_ALIAS declare_alias (RECODE_OUTER, bool declare_implied_surface (RECODE_OUTER, RECODE_ALIAS, RECODE_CONST_SYMBOL); bool make_argmatch_arrays (RECODE_OUTER); +void delete_alias (RECODE_ALIAS alias); RECODE_ALIAS find_alias (RECODE_OUTER, const char *, enum alias_find_type); bool find_and_report_subsets (RECODE_OUTER);