fix for adding ;' to nofork command substitution; IBM z/OS changes; fix for files ending with backslash; fix for expanding compound assignment in an alias; fix for printing here-documents in if statements; change to make enable -fn load a builtin but mark it as disabled; fix for removing FIFOs during .'; fix for single-quoting translations

This commit is contained in:
Chet Ramey
2023-06-03 14:21:03 -04:00
parent 353e3749e9
commit a629483b0e
16 changed files with 217 additions and 17 deletions
+54
View File
@@ -6494,3 +6494,57 @@ builtins/enable.def
- enable_builtin: don't try to load a builtin that's not found if
the -n flag is supplied.
From a report from Emanuele Torre <torreemanuele6@gmail.com>
parse.y
- parse_comsub: use was_word code again to make sure we add a closing
`;' if the last token parsed before the closing ';' or '\n' was a
word, no matter what character ends it.
From a report by Grisha Levit <grishalevit@gmail.com>
aclocal.m4,configure.ac,findcmd.c
- IBM z/OS changes from Igor Todorovski <itodorov@ca.ibm.com>
6/1
---
parse.y
- shell_getc: if the shell is not interactive and reading from a
buffered stream or stdin, and not expanding an alias, add a
backslash to a line ending with <backslash><EOF> like we do when
reading from a string. This prevents a backslash-newline from
being discarded when we are removing backslash-newlines from the
input, since we will add a newline to shell_input_line in this case.
From a report by Rob Landley <rob@landley.net>
parse.y
- parse_compound_assignment: check and compensate for an alias being
popped out from underneath this function by read_token() (e.g.,
alias L='m=("x")'. Since we don't push a new input source, we should
never restore pushed_string_list from the saved parser state, but
we check and only do this if we were expanding an alias when this
function was called.
From a report by Wiley Young <wyeth2485@gmail.com>
6/2
---
print_cmd.c
- print_if_command: make sure to print any pending here-documents after
printing the test.
From https://bugzilla.redhat.com/show_bug.cgi?id=2211214
builtins/enable.def
- if -n is supplied with -f, attempt to load the builtin but mark it
as disabled after loading.
Suggested by Robert Elz <kre@munnari.OZ.AU>
builtins/evalfile.c
- _evalfile: increment retain_fifos, so we don't delete any FIFOs or
pipes we inherited before sourcing this file; restore original value
before we return.
From https://savannah.gnu.org/support/index.php?110883
6/3
---
subst.c
- expand_string_dollar_quote: if singlequote_translations is set, there
is a chance for a use-after-free of `t'.
From a report by Grisha Levit <grishalevit@gmail.com>
+1
View File
@@ -1197,6 +1197,7 @@ tests/heredoc5.sub f
tests/heredoc6.sub f
tests/heredoc7.sub f
tests/heredoc8.sub f
tests/heredoc9.sub f
tests/herestr.tests f
tests/herestr.right f
tests/herestr1.sub f
Vendored
+6 -1
View File
@@ -1573,13 +1573,15 @@ AC_DEFUN(BASH_CHECK_DEV_FD,
[AC_MSG_CHECKING(whether /dev/fd is available)
AC_CACHE_VAL(bash_cv_dev_fd,
[bash_cv_dev_fd=""
if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then
if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then
# check for systems like FreeBSD 5 that only provide /dev/fd/[012]
if (exec test -r /dev/fd/3 3</dev/null) ; then
bash_cv_dev_fd=standard
else
bash_cv_dev_fd=absent
fi
elif test "$host_os" = "openedition" && (exec test -r /dev/fd0 < /dev/null); then
bash_cv_dev_fd=nodir # /dev/fdN via character device
fi
if test -z "$bash_cv_dev_fd" ; then
if test -d /proc/self/fd && (exec test -r /proc/self/fd/0 < /dev/null) ; then
@@ -1596,6 +1598,9 @@ if test $bash_cv_dev_fd = "standard"; then
elif test $bash_cv_dev_fd = "whacky"; then
AC_DEFINE(HAVE_DEV_FD)
AC_DEFINE(DEV_FD_PREFIX, "/proc/self/fd/")
elif test $bash_cv_dev_fd = "nodir"; then
AC_DEFINE(HAVE_DEV_FD)
AC_DEFINE(DEV_FD_PREFIX, "/dev/fd")
fi
])
+2
View File
@@ -435,6 +435,8 @@ dyn_load_builtin (WORD_LIST *list, int flags, char *filename)
b->flags &= ~STATIC_BUILTIN;
if (flags & SPECIAL)
b->flags |= SPECIAL_BUILTIN;
if (flags & DISABLED)
b->flags &= ~BUILTIN_ENABLED;
b->handle = handle;
if (old_builtin)
+4
View File
@@ -218,6 +218,7 @@ file_error_and_exit:
if (flags & FEVAL_NONINT)
unwind_protect_int (interactive);
unwind_protect_int (sourcelevel);
unwind_protect_int (retain_fifos);
}
else
{
@@ -232,6 +233,8 @@ file_error_and_exit:
return_catch_flag++;
sourcelevel++;
retain_fifos++; /* XXX */
#if defined (ARRAY_VARS)
array_push (bash_source_a, (char *)filename);
t = itos (executing_line_number ());
@@ -304,6 +307,7 @@ file_error_and_exit:
#endif
return_catch_flag--;
sourcelevel--;
retain_fifos--;
COPY_PROCENV (old_return_catch, return_catch);
}
Vendored
+11 -3
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac for Bash 5.2, version 5.051.
# From configure.ac for Bash 5.2, version 5.052.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for bash 5.2-maint.
#
@@ -3281,7 +3281,6 @@ m68k-sysv) opt_bash_malloc=no ;; # fixes file descriptor leak in closedir
*-beos*) opt_bash_malloc=no ;; # they say it's suitable
# These need additional investigation
sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
i370-*) opt_bash_malloc=no ;; # IBM z/OS machines
*-aix*) opt_bash_malloc=no ;; # AIX machines
*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
# These lack a working sbrk(2)
@@ -3299,6 +3298,8 @@ riscv*-freebsd*) opt_bash_malloc=no ;;
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
*-haiku*) opt_bash_malloc=no ;; # Haiku OS
*-genode*) opt_bash_malloc=no ;; # Genode has no sbrk
i370-openedition*) opt_bash_malloc=no LOCAL_LIBS=-lzoslib LIBS_FOR_BUILD=-lzoslib ;; # IBM z/OS machines
i370-*) opt_bash_malloc=no ;; # generic (?) IBM 370 machines
esac
# memory scrambling on free()
@@ -21628,13 +21629,15 @@ then :
printf %s "(cached) " >&6
else $as_nop
bash_cv_dev_fd=""
if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then
if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then
# check for systems like FreeBSD 5 that only provide /dev/fd/[012]
if (exec test -r /dev/fd/3 3</dev/null) ; then
bash_cv_dev_fd=standard
else
bash_cv_dev_fd=absent
fi
elif test "$host_os" = "openedition" && (exec test -r /dev/fd0 < /dev/null); then
bash_cv_dev_fd=nodir # /dev/fdN via character device
fi
if test -z "$bash_cv_dev_fd" ; then
if test -d /proc/self/fd && (exec test -r /proc/self/fd/0 < /dev/null) ; then
@@ -21658,6 +21661,11 @@ elif test $bash_cv_dev_fd = "whacky"; then
printf "%s\n" "#define DEV_FD_PREFIX \"/proc/self/fd/\"" >>confdefs.h
elif test $bash_cv_dev_fd = "nodir"; then
printf "%s\n" "#define HAVE_DEV_FD 1" >>confdefs.h
printf "%s\n" "#define DEV_FD_PREFIX \"/dev/fd\"" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether /dev/stdin stdout stderr are available" >&5
+3 -2
View File
@@ -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 <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 5.2, version 5.051])dnl
AC_REVISION([for Bash 5.2, version 5.052])dnl
define(bashvers, 5.2)
define(relstatus, maint)
@@ -75,7 +75,6 @@ m68k-sysv) opt_bash_malloc=no ;; # fixes file descriptor leak in closedir
*-beos*) opt_bash_malloc=no ;; # they say it's suitable
# These need additional investigation
sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
i370-*) opt_bash_malloc=no ;; # IBM z/OS machines
*-aix*) opt_bash_malloc=no ;; # AIX machines
*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
# These lack a working sbrk(2)
@@ -93,6 +92,8 @@ riscv*-freebsd*) opt_bash_malloc=no ;;
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
*-haiku*) opt_bash_malloc=no ;; # Haiku OS
*-genode*) opt_bash_malloc=no ;; # Genode has no sbrk
i370-openedition*) opt_bash_malloc=no LOCAL_LIBS=-lzoslib LIBS_FOR_BUILD=-lzoslib ;; # IBM z/OS machines
i370-*) opt_bash_malloc=no ;; # generic (?) IBM 370 machines
esac
# memory scrambling on free()
+12
View File
@@ -117,7 +117,19 @@ file_status (const char *name)
/* Determine whether this file exists or not. */
if (stat (name, &finfo) < 0)
#if defined (__MVS__) && defined (S_ISEXTL)
{
/* Workaround for z/OS not supporting stat on external links */
int old_errno = errno;
if (!(errno == ENOENT && lstat(name, &finfo) == 0 && S_ISEXTL(finfo.st_mode,finfo.st_genvalue)))
{
errno = old_errno; /* lstat may reset errno */
return (0);
}
}
#else
return (0);
#endif
/* If the file is a directory, then it is not "executable" in the
sense of the shell. */
+24 -4
View File
@@ -2603,6 +2603,10 @@ shell_getc (int remove_quoted_newline)
word expansion). */
if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
shell_input_line[shell_input_line_len] = '\\';
else if (bash_input.type == st_bstream && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
shell_input_line[shell_input_line_len] = '\\';
else if (interactive == 0 && bash_input.type == st_stream && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
shell_input_line[shell_input_line_len] = '\\';
else
shell_input_line[shell_input_line_len] = '\n';
shell_input_line[shell_input_line_len + 1] = '\0';
@@ -4384,7 +4388,6 @@ parse_comsub (int qc, int open, int close, size_t *lenp, int flags)
r = yyparse ();
#if 0
if (open == '{')
{
if (current_token == shell_eof_token &&
@@ -4392,7 +4395,6 @@ parse_comsub (int qc, int open, int close, size_t *lenp, int flags)
(token_before_that == WORD || token_before_that == ASSIGNMENT_WORD))
was_word = 1;
}
#endif
if (need_here_doc > 0)
{
@@ -4486,7 +4488,9 @@ INTERNAL_DEBUG(("current_token (%d) != shell_eof_token (%c)", current_token, she
ret = xmalloc (retlen + 4);
ret[0] = (dolbrace_spec == '|') ? '|' : ' ';
strcpy (ret + 1, tcmd); /* ( */
if (lastc != '\n' && lastc != ';' && lastc != '&')
if (was_word)
ret[retlen++] = ';';
else if (lastc != '\n' && lastc != ';' && lastc != '&')
ret[retlen++] = ';';
ret[retlen++] = ' ';
}
@@ -6853,9 +6857,10 @@ static char *
parse_compound_assignment (size_t *retlenp)
{
WORD_LIST *wl, *rl;
int tok, orig_line_number, assignok;
int tok, orig_line_number, assignok, ea, restore_pushed_strings;
sh_parser_state_t ps;
char *ret;
STRING_SAVER *ss;
orig_line_number = line_number;
save_parser_state (&ps);
@@ -6878,6 +6883,12 @@ parse_compound_assignment (size_t *retlenp)
esacs_needed_count = expecting_in_token = 0;
/* We're not pushing any new input here, we're reading from the current input
source. If that's an alias, we have to be prepared for the alias to get
popped out from underneath us. */
ss = (ea = expanding_alias ()) ? pushed_string_list : (STRING_SAVER *)NULL;
restore_pushed_strings = 0;
while ((tok = read_token (READ)) != ')')
{
if (tok == '\n') /* Allow newlines in compound assignments */
@@ -6901,7 +6912,16 @@ parse_compound_assignment (size_t *retlenp)
wl = make_word_list (yylval.word, wl);
}
/* Check whether or not an alias got popped out from underneath us and
fix up after restore_parser_state. */
if (ea && ss && ss != pushed_string_list)
{
restore_pushed_strings = 1;
ss = pushed_string_list;
}
restore_parser_state (&ps);
if (restore_pushed_strings)
pushed_string_list = ss;
if (wl == &parse_string_error)
{
+17 -2
View File
@@ -770,7 +770,14 @@ print_until_or_while (WHILE_COM *while_command, char *which)
make_command_string_internal (while_command->test);
PRINT_DEFERRED_HEREDOCS ("");
semicolon ();
cprintf (" do\n"); /* was newline ("do\n"); */
if (was_heredoc)
{
indent (indentation);
cprintf ("do\n");
was_heredoc = 0;
}
else
cprintf (" do\n"); /* was newline ("do\n"); */
indentation += indentation_amount;
make_command_string_internal (while_command->action);
PRINT_DEFERRED_HEREDOCS ("");
@@ -785,8 +792,16 @@ print_if_command (IF_COM *if_command)
cprintf ("if ");
skip_this_indent++;
make_command_string_internal (if_command->test);
PRINT_DEFERRED_HEREDOCS ("");
semicolon ();
cprintf (" then\n");
if (was_heredoc)
{
indent (indentation_amount);
cprintf ("then\n");
was_heredoc = 0;
}
else
cprintf (" then\n");
indentation += indentation_amount;
make_command_string_internal (if_command->true_case);
PRINT_DEFERRED_HEREDOCS ("");
+8 -3
View File
@@ -4231,12 +4231,17 @@ expand_string_dollar_quote (const char *string, int flags)
continue;
}
trans = locale_expand (t, 0, news-sindex, 0, &translen);
free (t);
if (singlequote_translations &&
((news-sindex-1) != translen || STREQN (t, trans, translen) == 0))
t = sh_single_quote (trans);
{
free (t);
t = sh_single_quote (trans);
}
else
t = sh_mkdoublequoted (trans, translen, 0);
{
free (t);
t = sh_mkdoublequoted (trans, translen, 0);
}
sindex = news;
}
#endif /* TRANSLATABLE_STRINGS */
+1
View File
@@ -3,6 +3,7 @@ alias: 0
./alias.tests: line 38: qfoo: command not found
quux
hi
declare -a m=([0]="x")
bar
value
bar
+4 -1
View File
@@ -54,9 +54,12 @@ unalias foo bar baz
alias foo='a=() b=""
for i in 1; do echo hi; done'
foo
unalias foo
alias L='m=("x")'
L
declare -p m
${THIS_SH} ./alias1.sub
${THIS_SH} ./alias2.sub
${THIS_SH} ./alias3.sub
+23 -1
View File
@@ -127,7 +127,29 @@ foo bar
./heredoc7.sub: line 29: foobar: command not found
./heredoc7.sub: line 30: EOF: command not found
grep: *.c: No such file or directory
foo ()
{
echo begin;
if cat <<HERE
contents
HERE
then
echo 1 2;
echo 3 4;
fi
}
foo ()
{
echo begin;
while read var <<HERE
contents
HERE
do
echo 1 2;
echo 3 4;
done
}
comsub here-string
./heredoc.tests: line 156: warning: here-document at line 154 delimited by end-of-file (wanted `EOF')
./heredoc.tests: line 159: warning: here-document at line 157 delimited by end-of-file (wanted `EOF')
hi
there
+3
View File
@@ -144,6 +144,9 @@ ${THIS_SH} ./heredoc6.sub
${THIS_SH} ./heredoc7.sub
${THIS_SH} ./heredoc8.sub
# various tests for printing here-documents in function bodies
${THIS_SH} ./heredoc9.sub
echo $(
cat <<< "comsub here-string"
)
+44
View File
@@ -0,0 +1,44 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# various issues with printing here-documents as part of function bodies
foo()
{
echo begin
if cat << HERE
contents
HERE
then
echo 1 2
echo 3 4
fi
}
declare -pf foo
foo()
{
echo begin
while read var << HERE
contents
HERE
do
echo 1 2
echo 3 4
done
}
declare -pf foo
unset -f foo