]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for -c command ending with backslash; fix several small memory leaks; fix several...
authorChet Ramey <chet.ramey@case.edu>
Mon, 26 Jun 2023 20:23:10 +0000 (16:23 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 26 Jun 2023 20:23:10 +0000 (16:23 -0400)
16 files changed:
CWRU/CWRU.chlog
arrayfunc.c
arrayfunc.h
bashline.c
builtins/cd.def
builtins/complete.def
builtins/evalstring.c
builtins/read.def
examples/loadables/kv.c
examples/loadables/stat.c
lib/readline/complete.c
lib/readline/input.c
lib/readline/kill.c
lib/sh/anonfile.c
parse.y
subst.c

index 5e88f380776738ee1c1d1aa3fb5779f79c1d807a..cb9fb332717da7aed89d8053dc5b9f8341365a9e 100644 (file)
@@ -6797,3 +6797,82 @@ lib/sh/anonfile.c
        - anonopen: use memfd_create if it is available, fall through to
          traditional Unix/POSIX implementation if it fails
 
+                                  6/20
+                                  ----
+parse.y
+       - yy_string_unget: don't push EOF back to a string, like the other
+         unget functions
+
+                                  6/21
+                                  ----
+parse.y
+       - read_a_line: don't push an EOF back into the string or line if the
+         line ends in a backslash.
+         From a report by Rob Landley <rob@landley.net>
+
+                                  6/22
+                                  ----
+lib/readline/input.c
+       - rl_gather_tyi: make sure result is initialized
+
+lib/readline/kill.c
+       - _rl_read_bracketed_paste_prefix: make sure key is initialized
+
+builtins/read.def
+       - read_builtin: make sure pass_next and saw_escape are initialized
+         before a possible goto
+       - read_builtin: make sure to initialize prevset for very short
+         timeouts
+
+subst.c
+       - function_substitute: make sure tflag is initialized even when we
+         don't call read_comsub, since we return it in ret->flags
+         All from a report by Grisha Levit <grishalevit@gmail.com>
+
+builtins/complete.def
+       - compgen_builtin: use array_from_argv to assign elements of the
+         stringlist to the array variable.
+         Update from Grisha Levit <grishalevit@gmail.com>
+
+builtins/cd.def
+       - bindpwd: fix seg fault from an unlikely set of circumstances
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+arrayfunc.h
+       - convert_validarray_flags_to_arrayval_flags: initialize avflags
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+lib/sh/anonfile.c
+       - anonopen: set *fn if memfd_create is used
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+                                  6/23
+                                  ----
+arrayfunc.c
+       - bind_assoc_var_internal: free key to fix small leak if assign_func
+         used
+       - quote_compound_array_word: free value to fix small leak
+
+builtins/evalstring.c
+       - parse_and_execute: free parsed command on failed function definition
+         import
+       - open_redir_file: free FN if we're not passing it back to the caller
+
+subst.c
+       - param_expand: free TEMP1 in code paths that don't do it now
+
+
+bashline.c
+       - bash_command_name_stat_hook: if we modify *NAME, free the old value
+
+examples/loadables/{kv,stat}.c
+       - bind_assoc_variable is caller-free VALUE, so free when needed and
+         don't allocate a new copy if not
+         All from a report by Grisha Levit <grishalevit@gmail.com>
+
+                                  6/24
+                                  ----
+lib/readline/complete.c
+       - rl_menu_complete: use _rl_free_match_list instead of just freeing
+         MATCHES if we have too many possible completions to display.
+         From a report by Grisha Levit <grishalevit@gmail.com>
index 74ff63166db428f1d96006d0f10fca28e2eda143..03eefe5ae4e780d8bef69ebb0396645f55529b73 100644 (file)
@@ -206,7 +206,10 @@ bind_assoc_var_internal (SHELL_VAR *entry, HASH_TABLE *hash, char *key, const ch
   newval = make_array_variable_value (entry, 0, key, value, flags);
 
   if (entry->assign_func)
-    (*entry->assign_func) (entry, newval, 0, key);
+    {
+      (*entry->assign_func) (entry, newval, 0, key);
+      FREE (key);
+    }
   else
     assoc_insert (hash, key, newval);
 
@@ -958,6 +961,7 @@ quote_compound_array_word (char *w, int type)
   if (t != w+ind)
    free (t);
   strcpy (nword + i, value);
+  free (value);
 
   return nword;
 }
index 08458c54218abc69f8c5fee03732ebed33f1c808..34f35b331bcdebc90251db83ecc74abe3cd86c78 100644 (file)
@@ -163,6 +163,7 @@ convert_validarray_flags_to_arrayval_flags (int vflags)
 {
   int avflags;  
 
+  avflags = 0;
   if (vflags & VA_NOEXPAND)
     avflags |= AV_NOEXPAND;
   if (vflags & VA_ONEWORD)
index 80f6860369d9c628b32b143d0969f771d65f0cc3..02f36e3ac28a720ac2ee012f82c1c9455d9b414b 100644 (file)
@@ -1922,6 +1922,7 @@ bash_command_name_stat_hook (char **name)
   result = search_for_command (cname, 0);
   if (result)
     {
+      FREE (*name);
       *name = result;
       return 1;
     }
index de123f8b2a7545fe46d3f93215a6f805ce58f4b4..e31564638fe83b9de85d655219f1b790dea44959 100644 (file)
@@ -158,10 +158,9 @@ bindpwd (int no_symlinks)
   pwdvar = get_string_value ("PWD");
 
   tvar = bind_variable ("OLDPWD", pwdvar, 0);
-  if (tvar && readonly_p (tvar))
+  if (tvar == 0 || readonly_p (tvar))
     r = EXECUTION_FAILURE;
-
-  if (old_anm == 0 && array_needs_making && exported_p (tvar))
+  else if (old_anm == 0 && array_needs_making && exported_p (tvar))
     {
       update_export_env_inplace ("OLDPWD=", 7, pwdvar);
       array_needs_making = 0;
index 890cf20d290c6613731199a9023701b0af698c67..74d966d5b28cda17685980524267a0697af36015 100644 (file)
@@ -678,7 +678,6 @@ compgen_builtin (WORD_LIST *list)
   int old_ind, old_completion, old_quoting, old_suppress;
   SHELL_VAR *var;
   char *varname;
-  WORD_LIST *alist;
 
   if (list == 0)
     return (EXECUTION_SUCCESS);
@@ -763,11 +762,7 @@ compgen_builtin (WORD_LIST *list)
       var = builtin_find_indexed_array (varname, 1);
       if (var && sl && sl->list && sl->list_len)
        {
-         alist = strlist_to_word_list (sl, 0, 0);
-         assign_array_var_from_word_list (var, alist, 0);
-         free (sl);
-         sl = (STRINGLIST *)NULL;
-         dispose_words (alist);
+         array_from_argv (array_cell (var), sl->list, sl->list_len);
          rval = EXECUTION_SUCCESS;
        }
     }
index 11785de1c1d2abfd4db7f40f7872bfa479d0660a..41198a942b000e162ed46ce22e2dff937aa45f3c 100644 (file)
@@ -415,6 +415,7 @@ parse_and_execute (char *string, const char *from_file, int flags)
                run_unwind_frame ("pe_dispose");
              last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
              set_pipestatus_from_exit (last_command_exit_value);
+             
              if (subshell_environment)
                {
                  should_jump_to_top_level = 1;
@@ -468,6 +469,8 @@ parse_and_execute (char *string, const char *from_file, int flags)
                      should_jump_to_top_level = 0;
                      last_result = last_command_exit_value = EX_BADUSAGE;
                      set_pipestatus_from_exit (last_command_exit_value);
+                     dispose_command (command);
+                     global_command = (COMMAND *)NULL;
                      reset_parser ();
                      break;
                    }
@@ -766,6 +769,9 @@ open_redir_file (REDIRECT *r, char **fnp)
 
   if (fnp)
     *fnp = fn;
+  else
+    free (fn);
+
   return fd;
 }
 
index cb4e1e59334d78b090f0309aab6384485e2d3ff0..5b2621fe2359ba4c4d1ab63988f5c2cbcdc99d25 100644 (file)
@@ -403,6 +403,9 @@ read_builtin (WORD_LIST *list)
   input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
   input_string[0] = '\0';
 
+  pass_next = 0;       /* Non-zero signifies last char was backslash. */
+  saw_escape = 0;      /* Non-zero signifies that we saw an escape char */
+
   /* More input and options validation */
   if (nflag == 1 && nchars == 0)
     {
@@ -428,6 +431,8 @@ read_builtin (WORD_LIST *list)
   sigemptyset (&chldset);
   sigprocmask (SIG_BLOCK, (sigset_t *)0, &chldset);
   sigaddset (&chldset, SIGCHLD);
+  sigemptyset (&prevset);
+  sigprocmask (SIG_SETMASK, (sigset_t *)0, &prevset);
 #endif
 
   begin_unwind_frame ("read_builtin");
@@ -463,9 +468,6 @@ read_builtin (WORD_LIST *list)
     add_unwind_protect (xfree, rlbuf);
 #endif
 
-  pass_next = 0;       /* Non-zero signifies last char was backslash. */
-  saw_escape = 0;      /* Non-zero signifies that we saw an escape char */
-
   if (tmsec > 0 || tmusec > 0)
     {
       /* Turn off the timeout if stdin is a regular file (e.g. from
@@ -495,7 +497,9 @@ read_builtin (WORD_LIST *list)
       if (code)
        {
          reset_timeout ();
+#if defined (SIGCHLD)
          sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0);
+#endif
 
          /* Tricky.  The top of the unwind-protect stack is the free of
             input_string.  We want to run all the rest and use input_string,
index 1dfceb6a7c7f616d67c34d8f4a4f1a5cf8ed1e94..ee6dc7f02c2832e56bb4703996add978d622300d 100644 (file)
@@ -71,7 +71,7 @@ kvsplit (SHELL_VAR *v, char *line, char *dstring)
   else
     value = "";
 
-  return (bind_assoc_variable (v, name_cell (v), savestring (key), savestring (value), 0) != 0);
+  return (bind_assoc_variable (v, name_cell (v), savestring (key), value, 0) != 0);
 }
 
 int
index 1093f7b059693adfd2d95751046a1156ab9c1887..d58f07e57b3a4cb41d0d2c5fffa496d80dd085b6 100644 (file)
@@ -330,6 +330,7 @@ loadstat (char *vname, SHELL_VAR *var, char *fname, int flags, char *fmt, struct
       key = savestring (arraysubs[i]);
       value = statval (i, fname, flags, fmt, sp);
       v = bind_assoc_variable (var, vname, key, value, ASS_FORCE);
+      free (value);
     }
   return 0;
 }
index 5aa97fd52c2946f89814a5e84530454eae0b85eb..05779f9741c34918f9662b999da03c100d027d3d 100644 (file)
@@ -2868,7 +2868,7 @@ rl_menu_complete (int count, int ignore)
          if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items)
            {
              rl_ding ();
-             FREE (matches);
+             _rl_free_match_list (matches);
              matches = (char **)0;
              full_completion = 1;
              return (0);
index 229474fff6dcca8efa6de670780d862267149a07..9807453065b166e01c3f5eb98b8fec584a5c151d 100644 (file)
@@ -249,6 +249,7 @@ rl_gather_tyi (void)
   struct timeval timeout;
 #endif
 
+  result = -1;
   chars_avail = 0;
   input = 0;
   tty = fileno (rl_instream);
index 0ba59ce5b96b84c0d0618ec46c620645f5aac85b..972c7d9e613c4a9de2519b775b7f091e0169c072 100644 (file)
@@ -779,7 +779,7 @@ _rl_read_bracketed_paste_prefix (int c)
   pbpref = BRACK_PASTE_PREF;           /* XXX - debugging */
   if (c != pbpref[0])
     return (0);
-  pbuf[ind = 0] = c;
+  pbuf[ind = 0] = key = c;
   while (ind < BRACK_PASTE_SLEN-1 &&
         (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
          _rl_pushed_input_available () == 0 &&
index 560b8c8662657a0c02ae0364143dd4eacbf36ab9..9a805b2d53728d6ad7ba355086863560e8efe4cc 100644 (file)
@@ -55,7 +55,11 @@ anonopen (const char *name, int flags, char **fn)
   /* "Names do not affect the behavior of the file descriptor." */
   fd = memfd_create ("anonopen", 0);
   if (fd >= 0)
-    return fd;
+    {
+      if (fn)
+       *fn = 0;
+      return fd;
+    }
   /* If memfd_create fails, we fall through to the unlinked-regular-file
      implementation. */
 #endif
diff --git a/parse.y b/parse.y
index c08b77f645fb2ec0a3d30fa61ed5dca0ed418528..6701d596ba3f5a660524a6841ddb58f74cfa4fe4 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -1696,6 +1696,9 @@ yy_string_get (void)
 static int
 yy_string_unget (int c)
 {
+  if (c == EOF && *bash_input.location.string == '\0')
+    return EOF;
+
   *(--bash_input.location.string) = c;
   return (c);
 }
@@ -2162,6 +2165,21 @@ read_a_line (int remove_quoted_newline)
              line_number++;
              continue; /* Make the unquoted \<newline> pair disappear. */
            }
+         else if (peekc == EOF)
+           {
+             /* Don't push EOF back. */
+#if 1
+             /* Leave this in for now, relies on how the expansion code
+                treats an unescaped backslash at the end of a word. */
+             RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
+             if (expanding_alias() == 0 &&
+                  (bash_input.type == st_string || bash_input.type == st_bstream ||
+                  (interactive == 0 && bash_input.type == st_stream)))
+               line_buffer[indx++] = '\\';     /* like below in shell_getc */
+#endif
+             line_buffer[indx++] = c;
+             c = '\n';                         /* force break below */
+           }
          else
            {
              yy_ungetc (peekc);
diff --git a/subst.c b/subst.c
index 11e7a00c942aa133526a45741abb35476bd5b04b..215e346948893341d03df923cb53be2c843356f6 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -7016,12 +7016,12 @@ function_substitute (char *string, int quoted, int flags)
 
   /* rewind back to the start of the file and read the contents */
 
+  tflag = 0;
   if (valsub == 0)
     {
       /* We call anonclose as part of the outer nofork unwind-protects */
       BLOCK_SIGNAL (SIGINT, set, oset);
       lseek (afd, 0, SEEK_SET);
-      tflag = 0;
       istring = read_comsub (afd, quoted, flags, &tflag);
       UNBLOCK_SIGNAL (oset);
     }
@@ -10840,6 +10840,7 @@ comsub:
            {
              chk_atstar (temp, quoted, pflags, quoted_dollar_at_p, contains_dollar_at);
              tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, 0);
+             free (temp1);
              if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
                return (tdesc);
              ret = tdesc;
@@ -10852,6 +10853,7 @@ comsub:
            {
              set_exit_status (EXECUTION_FAILURE);
              report_error (_("%s: invalid variable name for name reference"), temp);
+             free (temp1);
              return (&expand_wdesc_error);     /* XXX */
            }
          else