]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for local variable problem in EXIT trap; add sed-like behavior for null patterns...
authorChet Ramey <chet.ramey@case.edu>
Tue, 19 Jul 2022 15:42:23 +0000 (11:42 -0400)
committerChet Ramey <chet.ramey@case.edu>
Tue, 19 Jul 2022 15:42:23 +0000 (11:42 -0400)
12 files changed:
CWRU/CWRU.chlog
builtins/evalstring.c
configure
configure.ac
eval.c
jobs.c
parse.y
subst.c
tests/new-exp.right
tests/new-exp16.sub
variables.c
variables.h

index 01ff431262159dfab0e6ee0c66951df4baab7411..1c1cfed518e082a838bab84ca830a7ef7cbe7c00 100644 (file)
@@ -3777,3 +3777,39 @@ lib/readline/isearch.c
        - rl_display_search: don't call rl_redisplay_function before returning;
          rl_message already calls it. Reported by
          Frédéric Moulins <frederic@moulins.org>
+
+configure.ac
+       - bumped version to bash-5.2-rc2
+
+                                  7/18
+                                  ----
+jobs.c
+       - set_job_control: don't bother calling tcgetpgrp if shell_tty < 0,
+         since it will just fail
+
+variables.c
+       - reset_local_contexts: new function, delete all context tables
+         associated with shell functions and set variable_context to 0.
+         Called when we want to stop executing in a shell function without
+         going through the pop_context chain with its side effects
+
+variables.h
+       - reset_local_contexts: extern declaration
+
+builtins/evalstring.c
+       - parse_and_execute: call reset_local_contexts instead of setting
+         variable_context to 0
+
+eval.c
+       - reader_loop: call reset_local_contexts in cases where the shell has
+         longjmped for a fatal error and errexit is enabled (ERREXIT), but
+         not for other cases, and especially not for the exit builtin,
+         instead of just setting variable_context to 0. Fixes issue originally
+         reported by Robert Stoll <robert.stoll@tegonal.com>
+
+subst.c
+       - pat_subst: implement sed-like behavior when presented with a null
+         pattern that's anchored at the start or end of the string, or when
+         presented with a null string: process the replacement string for `&'
+         and `\&' and substitute in the result as before. Patch from
+         Koichi Murase <myoga.murase@gmail.com>
index 7023eb320b96dd7bf90f85c31f1effd0059da22f..fd635299581f57369fe999365d998de6669f7edb 100644 (file)
@@ -363,12 +363,14 @@ parse_and_execute (string, from_file, flags)
                 these circumstances.  Don't bother with cleanup here because
                 we don't want to run the function execution cleanup stuff
                 that will cause pop_context and other functions to run.
+                We call reset_local_contexts() instead, which just frees
+                context memory.
                 XXX - change that if we want the function context to be
                 unwound. */
              if (exit_immediately_on_error && variable_context)
                {
                  discard_unwind_frame ("pe_dispose");
-                 variable_context = 0; /* not in a function */
+                 reset_local_contexts (); /* not in a function */
                }
              should_jump_to_top_level = 1;
              goto out;
index 83f2a214818cf3ab15dd21e44b580aef5798fcf2..994f727568d794db2dfa804ffed7effc5a24d54f 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
-# From configure.ac for Bash 5.2, version 5.042.
+# From configure.ac for Bash 5.2, version 5.043.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for bash 5.2-rc1.
+# Generated by GNU Autoconf 2.71 for bash 5.2-rc2.
 #
 # Report bugs to <bug-bash@gnu.org>.
 #
@@ -612,8 +612,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='bash'
 PACKAGE_TARNAME='bash'
-PACKAGE_VERSION='5.2-rc1'
-PACKAGE_STRING='bash 5.2-rc1'
+PACKAGE_VERSION='5.2-rc2'
+PACKAGE_STRING='bash 5.2-rc2'
 PACKAGE_BUGREPORT='bug-bash@gnu.org'
 PACKAGE_URL=''
 
@@ -1467,7 +1467,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures bash 5.2-rc1 to adapt to many kinds of systems.
+\`configure' configures bash 5.2-rc2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1533,7 +1533,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of bash 5.2-rc1:";;
+     short | recursive ) echo "Configuration of bash 5.2-rc2:";;
    esac
   cat <<\_ACEOF
 
@@ -1740,7 +1740,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-bash configure 5.2-rc1
+bash configure 5.2-rc2
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2397,7 +2397,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by bash $as_me 5.2-rc1, which was
+It was created by bash $as_me 5.2-rc2, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3176,7 +3176,7 @@ ac_config_headers="$ac_config_headers config.h"
 
 
 BASHVERS=5.2
-RELSTATUS=rc1
+RELSTATUS=rc2
 
 case "$RELSTATUS" in
 alp*|bet*|dev*|rc*|releng*|maint*)     DEBUG='-DDEBUG' MALLOC_DEBUG='-DMALLOC_DEBUG' ;;
@@ -22369,7 +22369,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by bash $as_me 5.2-rc1, which was
+This file was extended by bash $as_me 5.2-rc2, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -22437,7 +22437,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-bash config.status 5.2-rc1
+bash config.status 5.2-rc2
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
index 47a000daa33c7e83e2c9bac8028d1a3d4530d961..034b3e23fb6d704d79e0cb2db4c364b12c3a467a 100644 (file)
@@ -21,10 +21,10 @@ dnl Process this file with autoconf to produce a configure script.
 #   You should have received a copy of the GNU General Public License
 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_REVISION([for Bash 5.2, version 5.042])dnl
+AC_REVISION([for Bash 5.2, version 5.043])dnl
 
 define(bashvers, 5.2)
-define(relstatus, rc1)
+define(relstatus, rc2)
 
 AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org])
 
diff --git a/eval.c b/eval.c
index 660e362d413f4f97c79964474765a25530480387..17fbf7366b4de3beab84f17e8d037bc5f0a61ae6 100644 (file)
--- a/eval.c
+++ b/eval.c
@@ -1,6 +1,6 @@
 /* eval.c -- reading and evaluating commands. */
 
-/* Copyright (C) 1996-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2022 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -90,13 +90,13 @@ reader_loop ()
          switch (code)
            {
              /* Some kind of throw to top_level has occurred. */
-           case FORCE_EOF:
            case ERREXIT:
+             if (exit_immediately_on_error)
+               reset_local_contexts ();        /* not in a function */
+           case FORCE_EOF:
            case EXITPROG:
            case EXITBLTIN:
              current_command = (COMMAND *)NULL;
-             if (exit_immediately_on_error)
-               variable_context = 0;   /* not in a function */
              EOF_Reached = EOF;
              goto exec_done;
 
diff --git a/jobs.c b/jobs.c
index 2c91fb0e6d6fef130e67bac5dd31822adb99f845..6b986ed76ace7e249198d61c04aff6da26f02823 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -4963,7 +4963,7 @@ set_job_control (arg)
   old = job_control;
   job_control = arg;
 
-  if (terminal_pgrp == NO_PID)
+  if (terminal_pgrp == NO_PID && shell_tty >= 0)
     terminal_pgrp = tcgetpgrp (shell_tty);
 
   /* If we're turning on job control we're going to want to know the shell's
diff --git a/parse.y b/parse.y
index 402ef0714392f1d8a37dd8a314492fe81a1a1540..0d6f91db8b987211ef190f3f34e8f1f46ce81a95 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -1200,7 +1200,7 @@ simple_list:      simple_list1
                        {
                          $$ = $1;
                          if (need_here_doc)
-                           gather_here_documents ();
+                           gather_here_documents ();   /* XXX */
                          if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
                            {
 INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 -> simple_list"));
@@ -1218,7 +1218,7 @@ INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 -> simple_li
                          else
                            $$ = command_connect ($1, (COMMAND *)NULL, '&');
                          if (need_here_doc)
-                           gather_here_documents ();
+                           gather_here_documents (); /* XXX */
                          if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
                            {
 INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 '&' -> simple_list"));
@@ -1233,7 +1233,7 @@ INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 '&' -> simpl
                        {
                          $$ = $1;
                          if (need_here_doc)
-                           gather_here_documents ();
+                           gather_here_documents ();   /* XXX */
                          if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
                            {
 INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 ';' -> simple_list"));
diff --git a/subst.c b/subst.c
index 163f42c1a7f764549188cdc279a48e4fc24f4f89..f3980166beea5035f9470cf2c630a8d77cf65a73 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -8930,37 +8930,34 @@ pat_subst (string, pat, rep, mflags)
    *       STRING and return the result.
    *   3.  A null STRING with a matching pattern means to append REP to
    *       STRING and return the result.
-   * These don't understand or process `&' in the replacement string.
+   *
+   * These process `&' in the replacement string, like `sed' does when
+   * presented with a BRE of `^' or `$'.
    */
   if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
     {
-      replen = STRLEN (rep);
+      rstr = (mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : rep;
+      rslen = STRLEN (rstr);
       l = STRLEN (string);
-      ret = (char *)xmalloc (replen + l + 2);
-      if (replen == 0)
+      ret = (char *)xmalloc (rslen + l + 2);
+      if (rslen == 0)
        strcpy (ret, string);
       else if (mtype == MATCH_BEG)
        {
-         strcpy (ret, rep);
-         strcpy (ret + replen, string);
+         strcpy (ret, rstr);
+         strcpy (ret + rslen, string);
        }
       else
        {
          strcpy (ret, string);
-         strcpy (ret + l, rep);
+         strcpy (ret + l, rstr);
        }
+      if (rstr != rep)
+       free (rstr);
       return (ret);
     }
   else if (*string == 0 && (match_pattern (string, pat, mtype, &s, &e) != 0))
-    {
-      replen = STRLEN (rep);
-      ret = (char *)xmalloc (replen + 1);
-      if (replen == 0)
-       ret[0] = '\0';
-      else
-       strcpy (ret, rep);
-      return (ret);
-    }
+    return ((mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : savestring (rep));
 
   ret = (char *)xmalloc (rsize = 64);
   ret[0] = '\0';
index 628e3ff8d73085d6e0ed3ae79b1d755b74c7d771..2d4d9b82ee6b252919bcae97361318bc655f951f 100644 (file)
@@ -780,6 +780,14 @@ let\&ee
 let\&ee
 let&ee
 let&ee
+twoone
+&twoone
+onetwo
+one&two
+two
+&two
+otwone
+&twone
 argv[1] = </>
 argv[1] = </>
 
index a48efb8444afa47285a0e4e81d4aafc3df780372..2ed751d34ce48e81df2037ad45eee64f0927409a 100644 (file)
@@ -101,3 +101,20 @@ echo ${var//$pat/"\&"}
 echo ${var//$pat/"$r3"}
 echo ${var//$pat/"&"}
 echo ${var//$pat/$r3}
+
+# these cases provide the same functionality as sed when given a BRE like
+# `^' or `$', or when passed a null input line
+one=one
+null=
+
+echo ${one/#/&two}
+echo ${one/#/\&two}
+
+echo ${one/%/&two}
+echo ${one/%/\&two}
+
+echo ${null/#/&two}
+echo ${null/#/\&two}
+
+echo ${one/#?/&two}
+echo ${one/#?/\&two}
index 941a904f3fe6c968aac1225a4d692d5dacb3060d..1a0c2c45c053fcce715ba2fa9095c41488994e70 100644 (file)
@@ -1,6 +1,6 @@
 /* variables.c -- Functions for hacking shell variables. */
 
-/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -330,6 +330,8 @@ static void push_func_var PARAMS((PTR_T));
 static void push_builtin_var PARAMS((PTR_T));
 static void push_exported_var PARAMS((PTR_T));
 
+static void delete_local_contexts PARAMS((VAR_CONTEXT *));
+
 /* This needs to be looked at again. */
 static inline void push_posix_tempvar_internal PARAMS((SHELL_VAR *, int));
 
@@ -5427,10 +5429,8 @@ pop_var_context ()
     internal_error (_("pop_var_context: no global_variables context"));
 }
 
-/* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
-   all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
-void
-delete_all_contexts (vcxt)
+static void
+delete_local_contexts (vcxt)
      VAR_CONTEXT *vcxt;
 {
   VAR_CONTEXT *v, *t;
@@ -5439,12 +5439,30 @@ delete_all_contexts (vcxt)
     {
       t = v->down;
       dispose_var_context (v);
-    }    
+    }
+}
 
+/* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
+   all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
+void
+delete_all_contexts (vcxt)
+     VAR_CONTEXT *vcxt;
+{
+  delete_local_contexts (vcxt);
   delete_all_variables (global_variables->table);
   shell_variables = global_variables;
 }
 
+/* Reset the context so we are not executing in a shell function. Only call
+   this if you are getting ready to exit the shell. */
+void
+reset_local_contexts ()
+{
+  delete_local_contexts (shell_variables);
+  shell_variables = global_variables;
+  variable_context = 0;
+}
+
 /* **************************************************************** */
 /*                                                                 */
 /*        Pushing and Popping temporary variable scopes            */
index d49ed0fba34be44ef71d1b2a7fc8bb4c6e49f508..55f497de062736a0d052d0706709115bed48b32b 100644 (file)
@@ -1,6 +1,6 @@
 /* variables.h -- data structures for shell variables. */
 
-/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -335,8 +335,10 @@ extern int unbind_function_def PARAMS((const char *));
 extern int delete_var PARAMS((const char *, VAR_CONTEXT *));
 extern int makunbound PARAMS((const char *, VAR_CONTEXT *));
 extern int kill_local_variable PARAMS((const char *));
+
 extern void delete_all_variables PARAMS((HASH_TABLE *));
 extern void delete_all_contexts PARAMS((VAR_CONTEXT *));
+extern void reset_local_contexts PARAMS((void));
 
 extern VAR_CONTEXT *new_var_context PARAMS((char *, int));
 extern void dispose_var_context PARAMS((VAR_CONTEXT *));