]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
avoid storing extra copy of function bodies; fix some minor memory leaks
authorChet Ramey <chet.ramey@case.edu>
Tue, 4 Jun 2024 16:23:18 +0000 (12:23 -0400)
committerChet Ramey <chet.ramey@case.edu>
Tue, 4 Jun 2024 16:23:18 +0000 (12:23 -0400)
CWRU/CWRU.chlog
builtins/declare.def
builtins/exec.def
parse.y
subst.c
variables.c

index b902d7c34591e385c802a0fb37be6f85b9efda00..54420f564d12a46975e44c89aa7d7dd478c871ba 100644 (file)
@@ -9590,3 +9590,39 @@ arrayfunc.c
        - assign_array_element_internal: if the assignment failed, as tested by
          ASSIGN_DISALLOWED, free the assoc array key we allocated
          Report from Grisha Levit <grishalevit@gmail.com>
+
+                                   6/3
+                                   ---
+variables.c
+       - bind_function_def: don't copy the command tree if we're overwriting
+         a function definition; after function binding, the function_def
+         struct never uses the saved command anyway
+         From a report and patch by Koichi Murase <myoga.murase@gmail.com>
+
+parse.y
+       - make sure to free WORD in coproc WORD COMMAND after creating the
+         coproc struct
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+builtins/exec.def
+       - exec_builtin: we don't need to set args to NULL; if shell_execve
+         reallocates args to add more items at the front, it has committed
+         to longjmp back to the top level
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+subst.c
+       - expand_word_internal: dispose of the list used for $@ if we're not
+         splitting and save the space-separated list back to tword->word
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+parse.y
+       - read_token: if we try to parse a conditional command and get a syntax
+         error, make sure to dispose of the partial command we created
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+       - read_token: if we try to parse a conditional command and get a syntax
+         error because we read an unexpected WORD, dispose of the WORD_DESC
+         before returning -1
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+       - cond_term: if we read a WORD where we expect something else, dispose
+         of the WORD_DESC before returning COND_ERROR
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
index 8065f8d28c959781b2c7e61b15f2254ac67bce93..b8e1f223a04ab61b0f4df8b452ac27ec4c926812 100644 (file)
@@ -156,6 +156,7 @@ declare_find_variable (const char *name, int mkglobal, int chklocal)
       var = find_variable (name);
       if (var && local_p (var) && var->context == variable_context)
        return var;
+      /* XXX - add check for previous scopes here if wanted 6/4/2024 */
       return (find_global_variable (name));
     }
   else
index 3ca7c4f8c58574fcb84474605a8cb40d441f5b98..618882c80c5cb4884eba9cec02ff38eb29c2b8f3 100644 (file)
@@ -230,10 +230,6 @@ exec_builtin (WORD_LIST *list)
   exit_value = shell_execve (command, args, env);
   opt = errno;
 
-  /* We have to set this to NULL because shell_execve has called realloc()
-     to stuff more items at the front of the array, which may have caused
-     the memory to be freed by realloc().  We don't want to free it twice. */
-  args = (char **)NULL;
   if (cleanenv == 0)
     adjust_shell_level (1);
 
diff --git a/parse.y b/parse.y
index 1349480be8db0f6943d8bb038576bcd10222910a..eb83af4c2197041cb2a7292bb6a9811cfe353418 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -1103,6 +1103,7 @@ coproc:           COPROC shell_command
                        {
                          $$ = make_coproc_command ($2->word, $3);
                          $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                         dispose_word ($2);
                        }
        |       COPROC WORD shell_command redirection_list
                        {
@@ -1120,6 +1121,7 @@ coproc:           COPROC shell_command
                            tc->redirects = $4;
                          $$ = make_coproc_command ($2->word, $3);
                          $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                         dispose_word ($2);
                        }
        |       COPROC simple_command
                        {
@@ -3518,15 +3520,20 @@ read_token (int command)
 #if defined (COND_COMMAND)
   if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
     {
+      COMMAND *cond_command;
       parser_state &= ~PST_CMDBLTIN;
       cond_lineno = line_number;
       parser_state |= PST_CONDEXPR;
-      yylval.command = parse_cond_command ();
+      cond_command = parse_cond_command ();
       if (cond_token != COND_END)
        {
          cond_error ();
+         if (cond_token == WORD)
+           dispose_word (yylval.word);
+         dispose_command (cond_command);
          return (-1);
        }
+      yylval.command = cond_command;
       token_to_read = COND_END;
       parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
       return (COND_CMD);
@@ -5042,7 +5049,7 @@ cond_term (void)
   else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
     {
       if (tok == WORD)
-       dispose_word (yylval.word);     /* not needed */
+       dispose_word (yylval.word);     /* word not needed */
       term = cond_term ();
       if (term)
        term->flags ^= CMD_INVERT_RETURN;
@@ -5118,6 +5125,8 @@ cond_term (void)
          else
            parser_error (line_number, _("conditional binary operator expected"));
          dispose_cond_node (tleft);
+         if (tok == WORD)
+           dispose_word (yylval.word);
          COND_RETURN_ERROR ();
        }
 
diff --git a/subst.c b/subst.c
index 929fabb26da177c6a4fdc13290d498976f6749ec..03205f951cac94766b88d6de6ba275b8eb4301fd 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -3472,6 +3472,7 @@ do_compound_assignment (const char *name, char *value, int flags)
   else if (mkglobal && variable_context)
     {
       v = chklocal ? find_variable (name) : 0;
+      /* XXX - if we want to make chklocal search previous scopes, change here 2024/06/04 */
       if (v && (local_p (v) == 0 || v->context != variable_context))
        v = 0;
       if (v == 0)
@@ -12144,6 +12145,7 @@ finished_with_string:
                 return, we expect to be able to split the results, but the
                 space separation means the right split doesn't happen. */
              tword->word = string_list (list); 
+             dispose_words (list);
            }
          else
            tword->word = istring;
@@ -12959,7 +12961,7 @@ expand_declaration_argument (WORD_LIST *tlist, WORD_LIST *wcmd)
   if (tlist->word->flags & W_ASSNGLOBAL)
     omap['g'] = 1;
   if (tlist->word->flags & W_CHKLOCAL)
-    omap['G'] = 1;
+    omap['G'] = 1;             /* internal, undocumented */
 
   /* If we have special handling note the integer attribute and others
      that transform the value upon assignment.  What we do is take all
index a64368e4a879db61b55356bedc298b9f916cb86b..e069ae5e5fc5020eaaaeaf43e9a998e08145121a 100644 (file)
@@ -3507,7 +3507,10 @@ bind_function_def (const char *name, FUNCTION_DEF *value, int flags)
   if (entry && (flags & 1))
     {
       dispose_function_def_contents (entry);
+      cmd = value->command;
+      value->command = 0;
       entry = copy_function_def_contents (value, entry);
+      value->command = cmd;
     }
   else if (entry)
     return;