From 08871a778096d2ac4aa4d94fa310686e13742ab5 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Sat, 6 Feb 2021 18:27:50 -0500 Subject: [PATCH] commit bash-20210201 snapshot --- CWRU/CWRU.chlog | 42 ++++++++++ Makefile.in | 1 + builtins/Makefile.in | 2 +- builtins/gen-helpfiles.c | 1 + configure | 4 +- configure.ac | 4 +- doc/Makefile.in | 7 +- examples/loadables/accept.c | 2 +- execute_cmd.c | 19 +++-- lib/glob/glob.c | 2 +- parse.y | 4 - subst.c | 158 ++++++++++++++++++++---------------- tests/alias.right | 1 + tests/alias.tests | 8 ++ tests/errors.right | 2 + tests/errors7.sub | 2 + 16 files changed, 169 insertions(+), 90 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index b5868a07..71cca9c9 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -9462,3 +9462,45 @@ execute_cmd.c exits unconditionally. - execute_simple_command: make sure posix mode sets $? to non-zero if a variable assignment error occurs preceding a non-special builtin + +subst.c + - do_assignment_statements: take the code from expand_word_list_internal + that performs assignment statements, either standalone or preceding + simple command names, and factor it out into this function + - expand_word_list_internal: call do_assignment_statements where + appropriate + + 2/2 + --- +lib/glob/glob.c + - dequote_pathname: fix function definition for non-multibyte systems. + Report and fix from Marc Aurèle La France + +Makefile.in,doc/Makefile.in + - for certain targets, remove files before creating them to deal with + symlinked build trees. + Report and fix from Marc Aurèle La France + +examples/loadables/accept.c + - include limits.h before typemax.h + Report and fix from Marc Aurèle La France + +builtins/gen-helpfiles.c + - if USING_BASH_MALLOC is defined, make sure to undefine malloc as well + as free. Fixes bug reported by George R Goffe + +builtins/Makefile.in + - install-help: now depends on $(HELPFILES_TARGET) so we make sure the + separate helpfiles are created before we try to install them if we + don't go through the `all' makefile target + +configure.ac + - HELPDIR: now ${datadir}/bash/helpfiles + + 2/3 + --- +parse.y + - parse_string_to_word_list: before expanding a compound assignment + statement body, make sure to save any alias that's currently being + expanded. Restore the alias after the compound assignment is parsed. + Reported back in 11/2020 by Alex fxmbsw7 Ratchev diff --git a/Makefile.in b/Makefile.in index fba0ccb2..e1f41463 100644 --- a/Makefile.in +++ b/Makefile.in @@ -649,6 +649,7 @@ ${GRAM_H}: y.tab.h y.tab.c: parse.y # -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi $(YACC) -d $(srcdir)/parse.y + $(RM) parser-built touch parser-built # -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; else cp -p y.tab.h ${GRAM_H}; fi diff --git a/builtins/Makefile.in b/builtins/Makefile.in index b349e93c..31fedc3e 100644 --- a/builtins/Makefile.in +++ b/builtins/Makefile.in @@ -203,7 +203,7 @@ builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC) helpdoc: gen-helpfiles ./gen-helpfiles ${HELPDIRDEFINE} -install-help: +install-help: $(HELPFILES_TARGET) @-if test -n "${HELPDIR}" && test -d helpfiles ; then \ test -d $(DESTDIR)${HELPDIR} || ${SHELL} ${MKDIRS} $(DESTDIR)$(HELPDIR) ;\ ( for f in helpfiles/*; do \ diff --git a/builtins/gen-helpfiles.c b/builtins/gen-helpfiles.c index 6bed4474..c9d6ea91 100644 --- a/builtins/gen-helpfiles.c +++ b/builtins/gen-helpfiles.c @@ -64,6 +64,7 @@ #undef xrealloc #undef xfree +#undef malloc #undef free /* defined in xmalloc.h */ #endif diff --git a/configure b/configure index 70dd0fa8..c449b254 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Bash 5.1, version 5.022. +# From configure.ac for Bash 5.1, version 5.023. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for bash 5.1-maint. # @@ -3400,7 +3400,7 @@ fi HELPDIR= HELPDIRDEFINE= HELPINSTALL= HELPFILES_TARGET= if test "$opt_separate_help" != no; then if test "$opt_separate_help" = "yes" ; then - HELPDIR='${datadir}/bash' + HELPDIR='${datadir}/bash/helpfiles' else HELPDIR=$opt_separate_help fi diff --git a/configure.ac b/configure.ac index eec8b38d..959ca097 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ 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 . -AC_REVISION([for Bash 5.1, version 5.022])dnl +AC_REVISION([for Bash 5.1, version 5.023])dnl define(bashvers, 5.1) define(relstatus, maint) @@ -368,7 +368,7 @@ fi HELPDIR= HELPDIRDEFINE= HELPINSTALL= HELPFILES_TARGET= if test "$opt_separate_help" != no; then if test "$opt_separate_help" = "yes" ; then - HELPDIR='${datadir}/bash' + HELPDIR='${datadir}/bash/helpfiles' else HELPDIR=$opt_separate_help fi diff --git a/doc/Makefile.in b/doc/Makefile.in index 12068fb5..7ec7afa1 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -173,23 +173,26 @@ html: ${HTMLFILES} pdf: ${PDFFILES} bashref.dvi: $(BASHREF_FILES) $(HSUSER) $(RLUSER) + $(RM) $@ ${SET_TEXINPUTS} $(TEXI2DVI) $(srcdir)/bashref.texi || { ${RM} $@ ; exit 1; } bashref.info: $(BASHREF_FILES) $(HSUSER) $(RLUSER) + $(RM) $@ $(MAKEINFO) --no-split -I$(TEXINPUTDIR) $(srcdir)/bashref.texi # experimental bashref.pdf: $(BASHREF_FILES) $(HSUSER) $(RLUSER) + $(RM) $@ ${SET_TEXINPUTS} $(TEXI2PDF) $(srcdir)/bashref.texi || { ${RM} $@ ; exit 1; } - # can also use: # $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi bashref.html: $(BASHREF_FILES) $(HSUSER) $(RLUSER) $(MAKEINFO) --html --no-split -I$(TEXINPUTDIR) $(srcdir)/bashref.texi bash.info: bashref.info - ${SHELL} ${INFOPOST} < $(srcdir)/bashref.info > $@ ; \ + $(RM) $@ + ${SHELL} ${INFOPOST} < $(srcdir)/bashref.info > $@ bash.txt: bash.1 bash.ps: bash.1 diff --git a/examples/loadables/accept.c b/examples/loadables/accept.c index 54cf38c8..d949699b 100644 --- a/examples/loadables/accept.c +++ b/examples/loadables/accept.c @@ -30,6 +30,7 @@ #include "bashtypes.h" #include #include +#include #include "typemax.h" #include @@ -44,7 +45,6 @@ int accept_builtin (list) WORD_LIST *list; { - WORD_LIST *l; SHELL_VAR *v; intmax_t iport; int opt; diff --git a/execute_cmd.c b/execute_cmd.c index e298ff4a..947e80b3 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -4452,21 +4452,24 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close) func = find_function (words->word->word); } - /* In POSIX mode, assignment errors in the temporary environment cause a - non-interactive shell executing a special builtin to exit and a non- - interactive shell to otherwise jump back to the top level. This is what - POSIX says to do for variable assignment errors, and errors in assigning - to the temporary environment are treated as variable assignment errors. */ + /* What happens in posix mode when an assignment preceding a command name + fails. This should agree with the code in execute_cmd.c: + do_assignment_statements(), even though I don't think it's executed any + more. */ if (posixly_correct && tempenv_assign_error) { +#if defined (DEBUG) + /* I don't know if this clause is ever executed, so let's check */ +itrace("execute_simple_command: posix mode tempenv assignment error"); +#endif last_command_exit_value = EXECUTION_FAILURE; #if defined (STRICT_POSIX) - jump_to_top_level ((interactive_shell == 0) ? ERREXIT : DISCARD); + jump_to_top_level ((interactive_shell == 0) ? FORCE_EOF : DISCARD); #else if (interactive_shell == 0 && builtin_is_special) - jump_to_top_level (ERREXIT); + jump_to_top_level (FORCE_EOF); else if (interactive_shell == 0) - jump_to_top_level (DISCARD); + jump_to_top_level (DISCARD); /* XXX - maybe change later */ else jump_to_top_level (DISCARD); #endif diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 8d1f426b..23952a11 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -119,10 +119,10 @@ void udequote_pathname PARAMS((char *)); #if HANDLE_MULTIBYTE void wcdequote_pathname PARAMS((wchar_t *)); static void wdequote_pathname PARAMS((char *)); +static void dequote_pathname PARAMS((char *)); #else # define dequote_pathname udequote_pathname #endif -static void dequote_pathname PARAMS((char *)); static int glob_testdir PARAMS((char *, int)); static char **glob_dir_to_array PARAMS((char *, char **, int)); diff --git a/parse.y b/parse.y index 4a0ca838..ab256e77 100644 --- a/parse.y +++ b/parse.y @@ -6493,10 +6493,8 @@ parse_string_to_word_list (s, flags, whom) old_expand_aliases = expand_aliases; push_stream (1); -#if 0 /* TAG: bash-5.2 Alex fxmbsw7 Ratchev 11/17/2020 */ if (ea = expanding_alias ()) parser_save_alias (); -#endif last_read_token = WORD; /* WORD to allow reserved words here */ current_command_line_count = 0; echo_input_at_read = expand_aliases = 0; @@ -6531,10 +6529,8 @@ parse_string_to_word_list (s, flags, whom) last_read_token = '\n'; pop_stream (); -#if 0 /* TAG: bash-5.2 */ if (ea) parser_restore_alias (); -#endif #if defined (HISTORY) remember_on_history = old_remember_on_history; diff --git a/subst.c b/subst.c index 03af0534..457c7325 100644 --- a/subst.c +++ b/subst.c @@ -361,6 +361,8 @@ static WORD_LIST *expand_declaration_argument PARAMS((WORD_LIST *, WORD_LIST *)) static WORD_LIST *shell_expand_word_list PARAMS((WORD_LIST *, int)); static WORD_LIST *expand_word_list_internal PARAMS((WORD_LIST *, int)); +static int do_assignment_statements PARAMS((WORD_LIST *, char *, int)); + /* **************************************************************** */ /* */ /* Utility Functions */ @@ -11966,6 +11968,87 @@ shell_expand_word_list (tlist, eflags) return (new_list); } +/* Perform assignment statements optionally preceding a command name COMMAND. + If COMMAND == NULL, is_nullcmd usually == 1. Follow the POSIX rules for + variable assignment errors. */ +static int +do_assignment_statements (varlist, command, is_nullcmd) + WORD_LIST *varlist; + char *command; + int is_nullcmd; +{ + WORD_LIST *temp_list; + char *savecmd; + sh_wassign_func_t *assign_func; + int is_special_builtin, is_builtin_or_func, tint; + + /* If the remainder of the words expand to nothing, Posix.2 requires + that the variable and environment assignments affect the shell's + environment (do_word_assignment). */ + assign_func = is_nullcmd ? do_word_assignment : assign_in_env; + tempenv_assign_error = 0; + + is_builtin_or_func = command && (find_shell_builtin (command) || find_function (command)); + /* Posix says that special builtins exit if a variable assignment error + occurs in an assignment preceding it. (XXX - this is old -- current Posix + says that any variable assignment error causes a non-interactive shell + to exit. See the STRICT_POSIX checks below. */ + is_special_builtin = posixly_correct && command && find_special_builtin (command); + + savecmd = this_command_name; + for (temp_list = varlist; temp_list; temp_list = temp_list->next) + { + this_command_name = (char *)NULL; + assigning_in_environment = is_nullcmd == 0; + tint = (*assign_func) (temp_list->word, is_builtin_or_func); + assigning_in_environment = 0; + this_command_name = savecmd; + + /* Variable assignment errors in non-interactive shells running + in posix mode cause the shell to exit. */ + if (tint == 0) + { + if (is_nullcmd) /* assignment statement */ + { + last_command_exit_value = EXECUTION_FAILURE; +#if defined (STRICT_POSIX) + if (posixly_correct && interactive_shell == 0) +#else + if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) +#endif + exp_jump_to_top_level (FORCE_EOF); + else + exp_jump_to_top_level (DISCARD); + } + /* In posix mode, assignment errors in the temporary environment + cause a non-interactive shell executing a special builtin to + exit and a non-interactive shell to otherwise jump back to the + top level. This is what POSIX says to do for variable assignment + errors, and POSIX says errors in assigning to the temporary + environment are treated as variable assignment errors. + (XXX - this is not what current POSIX says - look at the + STRICT_POSIX defines. */ + else if (posixly_correct) + { + last_command_exit_value = EXECUTION_FAILURE; +#if defined (STRICT_POSIX) + exp_jump_to_top_level ((interactive_shell == 0) ? FORCE_EOF : DISCARD); +#else + if (interactive_shell == 0 && is_special_builtin) + exp_jump_to_top_level (FORCE_EOF); + else if (interactive_shell == 0) + exp_jump_to_top_level (DISCARD); /* XXX - maybe change later */ + else + exp_jump_to_top_level (DISCARD); +#endif + } + else + tempenv_assign_error++; + } + } + return (tempenv_assign_error); +} + /* The workhorse for expand_words () and expand_words_no_vars (). First arg is LIST, a WORD_LIST of words. Second arg EFLAGS is a flags word controlling which expansions are @@ -11985,8 +12068,6 @@ expand_word_list_internal (list, eflags) int eflags; { WORD_LIST *new_list, *temp_list; - int tint; - char *savecmd; tempenv_assign_error = 0; if (list == 0) @@ -11999,30 +12080,11 @@ expand_word_list_internal (list, eflags) if (new_list == 0) { if (subst_assign_varlist) - { - /* All the words were variable assignments, so they are placed - into the shell's environment. */ - for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next) - { - savecmd = this_command_name; - this_command_name = (char *)NULL; /* no arithmetic errors */ - tint = do_word_assignment (temp_list->word, 0); - this_command_name = savecmd; - /* Variable assignment errors in non-interactive shells - running in Posix.2 mode cause the shell to exit, unless - they are being run by the `command' builtin. */ - if (tint == 0) - { - last_command_exit_value = EXECUTION_FAILURE; - if (interactive_shell == 0 && posixly_correct && executing_command_builtin == 0) - exp_jump_to_top_level (FORCE_EOF); - else - exp_jump_to_top_level (DISCARD); - } - } - dispose_words (subst_assign_varlist); - subst_assign_varlist = (WORD_LIST *)NULL; - } + do_assignment_statements (subst_assign_varlist, (char *)NULL, 1); + + dispose_words (subst_assign_varlist); + subst_assign_varlist = (WORD_LIST *)NULL; + return ((WORD_LIST *)NULL); } } @@ -12056,49 +12118,7 @@ expand_word_list_internal (list, eflags) if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist) { - sh_wassign_func_t *assign_func; - int is_special_builtin, is_builtin_or_func; - - /* If the remainder of the words expand to nothing, Posix.2 requires - that the variable and environment assignments affect the shell's - environment. */ - assign_func = new_list ? assign_in_env : do_word_assignment; - tempenv_assign_error = 0; - - is_builtin_or_func = (new_list && new_list->word && (find_shell_builtin (new_list->word->word) || find_function (new_list->word->word))); - /* Posix says that special builtins exit if a variable assignment error - occurs in an assignment preceding it. */ - is_special_builtin = (posixly_correct && new_list && new_list->word && find_special_builtin (new_list->word->word)); - - for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next) - { - savecmd = this_command_name; - this_command_name = (char *)NULL; - assigning_in_environment = (assign_func == assign_in_env); - tint = (*assign_func) (temp_list->word, is_builtin_or_func); - assigning_in_environment = 0; - this_command_name = savecmd; - /* Variable assignment errors in non-interactive shells running - in Posix.2 mode cause the shell to exit. */ - if (tint == 0) - { - if (assign_func == do_word_assignment) - { - last_command_exit_value = EXECUTION_FAILURE; - if (interactive_shell == 0 && posixly_correct) - exp_jump_to_top_level (FORCE_EOF); - else - exp_jump_to_top_level (DISCARD); - } - else if (interactive_shell == 0 && is_special_builtin) - { - last_command_exit_value = EXECUTION_FAILURE; - exp_jump_to_top_level (FORCE_EOF); - } - else - tempenv_assign_error++; - } - } + do_assignment_statements (subst_assign_varlist, (new_list && new_list->word) ? new_list->word->word : (char *)NULL, new_list == 0); dispose_words (subst_assign_varlist); subst_assign_varlist = (WORD_LIST *)NULL; diff --git a/tests/alias.right b/tests/alias.right index 9e33036b..475f8b31 100644 --- a/tests/alias.right +++ b/tests/alias.right @@ -2,6 +2,7 @@ alias: 0 alias: 0 ./alias.tests: line 38: qfoo: command not found quux +hi bar value bar diff --git a/tests/alias.tests b/tests/alias.tests index 0280c16d..c270661c 100644 --- a/tests/alias.tests +++ b/tests/alias.tests @@ -49,6 +49,14 @@ foo bar unalias foo bar baz +# post bash-5.1 problems with compound array assignment during multiline +# alias expansion +alias foo='a=() b="" +for i in 1; do echo hi; done' +foo + +unalias foo + ${THIS_SH} ./alias1.sub ${THIS_SH} ./alias2.sub ${THIS_SH} ./alias3.sub diff --git a/tests/errors.right b/tests/errors.right index 9d0e2c0d..f3e925c5 100644 --- a/tests/errors.right +++ b/tests/errors.right @@ -176,12 +176,14 @@ after non-special builtin: 0 ./errors7.sub: line 25: x: readonly variable after special builtin: 0 ./errors7.sub: line 27: x: readonly variable +./errors7.sub: line 29: x: readonly variable ./errors7.sub: line 21: x: readonly variable after no such command: 1 ./errors7.sub: line 23: x: readonly variable after non-special builtin: 1 ./errors7.sub: line 25: x: readonly variable ./errors7.sub: line 27: x: readonly variable +./errors7.sub: line 29: x: readonly variable ./errors8.sub: eval: line 7: syntax error: unexpected end of file ok 1 ./errors8.sub: line 8: v: readonly variable diff --git a/tests/errors7.sub b/tests/errors7.sub index add8782a..544e3e4c 100644 --- a/tests/errors7.sub +++ b/tests/errors7.sub @@ -26,3 +26,5 @@ echo after non-special builtin: $? echo after special builtin: $? ) ( x=8 $nocmd echo after assignment error: $? ) +( x=8 +echo after assignment statement error: $? )