From 8a286b63457628b0a55d395f14005f254512e27d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 8 Aug 2016 12:19:29 +0100 Subject: [PATCH] Fix memory leaks in chew program. * doc/chew.c (delete_string): Only free the string buffer if it is there. Mark the buffer as NULL after freeing. (drop): Free the dropped string. (free_words): New function: Frees the memory allocated to the dictionary. (add_instrinsic): Duplicate the name string, so that it can be freed later on. (compile): Free unused words. (main): Free the dictionary and top level string buffers at the end. --- bfd/ChangeLog | 13 +++++++++++++ bfd/doc/chew.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9c0f439b89..0b19c6162d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2016-08-08 Nick Clifton + + * doc/chew.c (delete_string): Only free the string buffer if it is + there. Mark the buffer as NULL after freeing. + (drop): Free the dropped string. + (free_words): New function: Frees the memory allocated to the + dictionary. + (add_instrinsic): Duplicate the name string, so that it can be + freed later on. + (compile): Free unused words. + (main): Free the dictionary and top level string buffers at the + end. + 2016-08-04 Thomas Preud'homme * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add one parameter. diff --git a/bfd/doc/chew.c b/bfd/doc/chew.c index 92b62cd413..71c7e2dc88 100644 --- a/bfd/doc/chew.c +++ b/bfd/doc/chew.c @@ -170,7 +170,9 @@ static void delete_string (buffer) string_type *buffer; { - free (buffer->ptr); + if (buffer->ptr) + free (buffer->ptr); + buffer->ptr = NULL; } static char * @@ -1088,6 +1090,7 @@ drop () { tos--; check_range (); + delete_string (tos + 1); pc++; } @@ -1243,6 +1246,35 @@ lookup_word (word) return 0; } +static void +free_words (void) +{ + dict_type *ptr = root; + + while (ptr) + { + dict_type *next; + + if (ptr->word) + free (ptr->word); + if (ptr->code) + { + int i; + for (i = 0; i < ptr->code_length; i ++) + if (ptr->code[i] == push_text + && ptr->code[i + 1]) + { + free (ptr->code[i + 1] - 1); + ++ i; + } + free (ptr->code); + } + next = ptr->next; + free (ptr); + ptr = next; + } +} + static void perform () { @@ -1313,7 +1345,7 @@ add_intrinsic (name, func) char *name; void (*func) (); { - dict_type *new_d = newentry (name); + dict_type *new_d = newentry (strdup (name)); add_to_definition (new_d, func); add_to_definition (new_d, 0); } @@ -1334,24 +1366,27 @@ compile (string) { /* Add words to the dictionary. */ char *word; + string = nextword (string, &word); while (string && *string && word[0]) { if (strcmp (word, "var") == 0) { + free (word); string = nextword (string, &word); - add_var (word); string = nextword (string, &word); } else if (word[0] == ':') { dict_type *ptr; + /* Compile a word and add to dictionary. */ + free (word); string = nextword (string, &word); - ptr = newentry (word); string = nextword (string, &word); + while (word[0] != ';') { switch (word[0]) @@ -1376,15 +1411,19 @@ compile (string) function */ add_to_definition (ptr, push_number); add_to_definition (ptr, (stinst_type) atol (word)); + free (word); break; default: add_to_definition (ptr, call); add_to_definition (ptr, (stinst_type) lookup_word (word)); + free (word); } string = nextword (string, &word); } add_to_definition (ptr, 0); + free (word); + word = NULL; string = nextword (string, &word); } else @@ -1392,6 +1431,8 @@ compile (string) fprintf (stderr, "syntax error at %s\n", string - 1); } } + if (word) + free (word); } static void @@ -1575,6 +1616,9 @@ main (ac, av) } } write_buffer (stack + 0, stdout); + free_words (); + delete_string (&pptr); + delete_string (&buffer); if (tos != stack) { fprintf (stderr, "finishing with current stack level %ld\n", -- 2.34.1