]> granicus.if.org Git - recode/commitdiff
Fix a potential memory leak in declare_single
authorReuben Thomas <rrt@sc3d.org>
Fri, 26 Jan 2018 12:11:33 +0000 (12:11 +0000)
committerReuben Thomas <rrt@sc3d.org>
Fri, 26 Jan 2018 13:28:11 +0000 (13:28 +0000)
src/names.c
src/outer.c
src/recodext.h

index 5d47c51f80cda1bef6dfef139aa84fbe74a958c3..46f7b2161e5c587fe958212eeb66d54b1813d3df 100644 (file)
@@ -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;
     }
 
index c8f5745ae1bf2e35b679612d904391ffdb70d6ff..c1134aed22476213e95a58061a29b7d785ad16a6 100644 (file)
@@ -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;
index aad1340eb0fbe8a3822c4eb56e635dfc983a8c97..5d371305c3d69309486784bd12a0a719b631207e 100644 (file)
@@ -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);