]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for interactive shell parser reset issue; fix for nested array subscript quoting...
authorChet Ramey <chet.ramey@case.edu>
Mon, 24 Oct 2022 14:09:52 +0000 (10:09 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 24 Oct 2022 14:09:52 +0000 (10:09 -0400)
CWRU/CWRU.chlog
execute_cmd.c
execute_cmd.h
lib/readline/xmalloc.c
parse.y
sig.c
subst.c
tests/posixexp.right

index 50a8219aac4d6131c55a2563391eadcaed187541..ba4454e9e5554e9f53533121edd520a57c2a633a 100644 (file)
@@ -4195,3 +4195,27 @@ subst.c
          command string (it was run through parse.y:parse_matched_pair())
        - expand_word_internal: pass PF_BACKQUOTE to command_substitute() if
          expanding a `` command substitution
+
+                                  10/20
+                                  -----
+parse.y
+       - yylex: return YYUNDEF as current_token if read_token returns < 0.
+         Fixes parser reset issue reported by Todd Stein <toddbstein@gmail.com>
+
+subst.c
+       - ARITH_EXP_CHARS: chars that are special and trigger expansion in
+         arithmetic expressions, EXP_CHARS without `<' and `>'. Fixes bug
+         reported by Glenn Jackman <glenn.jackman@gmail.com>
+
+execute_cmd.c
+       - retain_fifos: replace executing_list (which is still present) as the
+         indicator of whether or not to save and restore the FIFO list around
+         a call to execute_command_internal/execute_command; it's more
+         descriptive and can be used elsewhere
+       - execute_for_command: set retain_fifos so we don't unlink the fifo
+         list until the for command completes. Fixes issue reported in
+         https://savannah.gnu.org/support/index.php?110743
+
+lib/readline/xmalloc.c
+       - memory_error_and_abort: add `const' qualifiers to the argument. Fix
+         from Markus Elfring <Markus.Elfring@web.de>
index b106645113eaae3f2100702565986db32340ac7c..04f79324cf3fca7edde6e6021e3e4e199235d8f9 100644 (file)
@@ -240,6 +240,9 @@ int executing_builtin = 0;
 /* Non-zero if we are executing a command list (a;b;c, etc.) */
 int executing_list = 0;
 
+/* Non-zero if we should defer closing process substitution FDs. */
+int retain_fifos = 0;
+
 /* Non-zero if failing commands in a command substitution should not exit the
    shell even if -e is set.  Used to pass the CMD_IGNORE_RETURN flag down to
    commands run in command substitutions by parse_and_execute. */
@@ -418,7 +421,7 @@ execute_command (command)
 #if defined (PROCESS_SUBSTITUTION)
   /* don't unlink fifos if we're in a shell function; wait until the function
      returns. */
-  if (variable_context == 0 && executing_list == 0)
+  if (variable_context == 0 && retain_fifos == 0)
     unlink_fifo_list ();
 #endif /* PROCESS_SUBSTITUTION */
 
@@ -779,7 +782,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
 #  endif
 
   /* XXX - also if sourcelevel != 0? */
-  if (variable_context != 0 || executing_list)
+  if (variable_context != 0 || retain_fifos)
     {
       ofifo = num_fifos ();
       ofifo_list = copy_fifo_list ((int *)&osize);
@@ -2749,7 +2752,7 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
          if (command->value.Connection->second)
            command->value.Connection->second->flags |= CMD_IGNORE_RETURN;
        }
-      executing_list++;
+      executing_list++; retain_fifos++;
       QUIT;
 
 #if 1
@@ -2765,7 +2768,7 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
       exec_result = execute_command_internal (command->value.Connection->second,
                                      asynchronous, pipe_in, pipe_out,
                                      fds_to_close);
-      executing_list--;
+      executing_list--; retain_fifos--;
       break;
 
     case '|':
@@ -2819,7 +2822,7 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
         and the connector is OR_OR, then execute the second command,
         otherwise return. */
 
-      executing_list++;
+      executing_list++; retain_fifos++;
       if (command->value.Connection->first)
        command->value.Connection->first->flags |= CMD_IGNORE_RETURN;
 
@@ -2842,7 +2845,7 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
 
          exec_result = execute_command (second);
        }
-      executing_list--;
+      executing_list--; retain_fifos--;
       break;
 
     default:
@@ -2890,7 +2893,7 @@ execute_for_command (for_command)
       return (EXECUTION_FAILURE);
     }
 
-  loop_level++;
+  loop_level++; retain_fifos++;
   identifier = for_command->name->word;
 
   line_number = for_command->line;     /* for expansion error messages */
@@ -2970,7 +2973,7 @@ execute_for_command (for_command)
            {
              dispose_words (releaser);
              discard_unwind_frame ("for");
-             loop_level--;
+             loop_level--; retain_fifos--;
              return (EXECUTION_FAILURE);
            }
        }
@@ -2998,7 +3001,7 @@ execute_for_command (for_command)
        }
     }
 
-  loop_level--;
+  loop_level--; retain_fifos--;
   line_number = save_line_number;
 
 #if 0
@@ -5757,8 +5760,8 @@ parent_return:
 
       /* Make sure that the pipes are closed in the parent. */
       close_pipes (pipe_in, pipe_out);
-#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
 #if 0
+#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
       if (variable_context == 0)
         unlink_fifo_list ();
 #endif
@@ -5914,7 +5917,7 @@ initialize_subshell ()
   /* We're no longer inside a shell function. */
   variable_context = return_catch_flag = funcnest = evalnest = sourcenest = 0;
 
-  executing_list = 0;          /* XXX */
+  executing_list = retain_fifos = 0;           /* XXX */
 
   /* If we're not interactive, close the file descriptor from which we're
      reading the current shell script. */
index 465030aef3929b33777104ce5715e02464c4ee40..d1545f0dd42a0ab3c34d7bc5ce86c57c3b356c2a 100644 (file)
@@ -52,6 +52,7 @@ extern int last_command_exit_signal;
 extern int builtin_ignoring_errexit;
 extern int executing_builtin;
 extern int executing_list;
+extern int retain_fifos;
 extern int comsub_ignore_return;
 extern int subshell_level;
 extern int match_ignore_case;
index 5d01d75eaeff07805e10fb512dc70949a59c6040..35e46eafea829a01f68d2fed6d0dab2c884dfc7a 100644 (file)
@@ -42,7 +42,7 @@
 /* **************************************************************** */
 
 static void
-memory_error_and_abort (char *fname)
+memory_error_and_abort (const char * const fname)
 {
   fprintf (stderr, "%s: out of virtual memory\n", fname);
   exit (2);
diff --git a/parse.y b/parse.y
index 11b71d4bfab3b057fbc27961405a5ccf017766e6..02b2af1fc0033766b7ec2fee93b57db2a44acdbc 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -2899,7 +2899,7 @@ yylex ()
 #if defined (YYERRCODE) && !defined (YYUNDEF)
     current_token = YYERRCODE;
 #else
-    current_token = YYerror;
+    current_token = YYUNDEF;
 #endif
 
   return (current_token);
@@ -4156,7 +4156,9 @@ parse_comsub (qc, open, close, lenp, flags)
       shell_eof_token = ps.eof_token;
       expand_aliases = ps.expand_aliases;
 
-      /* yyparse() has already called yyerror() and reset_parser() */
+      /* yyparse() has already called yyerror() and reset_parser(), so we set
+        PST_NOERROR to avoid a redundant error message. */
+      parser_state |= PST_NOERROR;
       return (&matched_pair_error);
     }
   else if (r != 0)
diff --git a/sig.c b/sig.c
index 0d31cb4fcc4ee0e56b2a560913d94276bace7181..bdead5c549348daaac557755e433bb85be34a17a 100644 (file)
--- a/sig.c
+++ b/sig.c
@@ -393,7 +393,8 @@ top_level_cleanup ()
 
   run_unwind_protects ();
   loop_level = continuing = breaking = funcnest = 0;
-  executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
+  executing_list = retain_fifos = 0;
+  comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
 }
 
 /* What to do when we've been interrupted, and it is safe to handle it. */
@@ -454,7 +455,8 @@ throw_to_top_level ()
 
   run_unwind_protects ();
   loop_level = continuing = breaking = funcnest = 0;
-  executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
+  executing_list = retain_fifos = 0;
+  comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
 
   if (interactive && print_newline)
     {
@@ -617,7 +619,8 @@ termsig_handler (sig)
 
   /* Reset execution context */
   loop_level = continuing = breaking = funcnest = 0;
-  executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
+  executing_list = retain_fifos = 0;
+  comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
 
   run_exit_trap ();    /* XXX - run exit trap possibly in signal context? */
 
diff --git a/subst.c b/subst.c
index ebc9b715cb7bf9254ce3fde524428da2832232eb..c4fb7732af710a2a14edf59dcee30125682007f4 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -3824,6 +3824,10 @@ pos_params (string, start, end, quoted, pflags)
 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
 #endif
 
+/* We don't perform process substitution in arithmetic expressions, so don't
+   bother checking for it. */
+#define ARITH_EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
+
 /* If there are any characters in STRING that require full expansion,
    then call FUNC to expand STRING; otherwise just perform quote
    removal if necessary.  This returns a new string. */
@@ -4033,7 +4037,7 @@ expand_arith_string (string, quoted)
   i = saw_quote = 0;
   while (string[i])
     {
-      if (EXP_CHAR (string[i]))
+      if (ARITH_EXP_CHAR (string[i]))
        break;
       else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
        saw_quote = string[i];
index 7204b960a99fc39d7abd94e4f53356c86e7bc006..d07be94735aa24bc3dd400effd60ee4c07c08439 100644 (file)
@@ -306,3 +306,4 @@ argv[1] = <"A">
 argv[1] = <A>
 argv[1] = <A>
 ./posixexp.tests: line 97: unexpected EOF while looking for matching `}'
+./posixexp.tests: line 98: syntax error: unexpected end of file