- 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>
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
[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
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
])
b->flags &= ~STATIC_BUILTIN;
if (flags & SPECIAL)
b->flags |= SPECIAL_BUILTIN;
+ if (flags & DISABLED)
+ b->flags &= ~BUILTIN_ENABLED;
b->handle = handle;
if (old_builtin)
if (flags & FEVAL_NONINT)
unwind_protect_int (interactive);
unwind_protect_int (sourcelevel);
+ unwind_protect_int (retain_fifos);
}
else
{
return_catch_flag++;
sourcelevel++;
+ retain_fifos++; /* XXX */
+
#if defined (ARRAY_VARS)
array_push (bash_source_a, (char *)filename);
t = itos (executing_line_number ());
#endif
return_catch_flag--;
sourcelevel--;
+ retain_fifos--;
COPY_PROCENV (old_return_catch, return_catch);
}
#! /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.
#
*-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)
*-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()
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
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
# 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)
*-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)
*-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()
/* 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. */
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';
r = yyparse ();
-#if 0
if (open == '{')
{
if (current_token == shell_eof_token &&
(token_before_that == WORD || token_before_that == ASSIGNMENT_WORD))
was_word = 1;
}
-#endif
if (need_here_doc > 0)
{
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++] = ' ';
}
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);
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 */
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)
{
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 ("");
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 ("");
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 */
./alias.tests: line 38: qfoo: command not found
quux
hi
+declare -a m=([0]="x")
bar
value
bar
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
./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
${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"
)
--- /dev/null
+# 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