fix for nofork comsubs undoing enclosing command's redirections; fix for binding _ variable in the temporary environment; fix for crash when making special variables arrays; accommodate IFS as array variable; fix for SIGINT arriving while cleaning up a readline incremental search

This commit is contained in:
Chet Ramey
2025-08-20 11:08:28 -04:00
parent 3160c0b89c
commit 0864568359
21 changed files with 131 additions and 20 deletions
+39
View File
@@ -11586,3 +11586,42 @@ builtins/declare.def
an invalid value for a nameref variable, but the original value is
valid, add an error message for the assignment error
Report from Oğuz <oguzismailuysal@gmail.com>
8/12
----
subst.c
- function_substitute: unwind-protect redirection_undo_list and
exec_redirection_undo_list so the funsub command doesn't undo them
prematurely
Report from jdhedden@gmail.com
8/13
----
execute_cmd.c
- bind_lastarg: don't try to bind the argument in the temporary
environment; just skip that and bind in the closest enclosing
scope
Report from Nathan Mills <the.true.nathan.mills@gmail.com>
8/15
----
arrayfunc.c
- convert_var_to_array,convert_var_to_assoc: call
stupidly_hack_special_variables to clean up any state associated
with the variable (e.g., IFS).
Report from Nathan Mills <the.true.nathan.mills@gmail.com>
subst.c
- setifs: if a script attempts to make IFS an array variable, use
element 0 or "0" as appropriate.
Report from Nathan Mills <the.true.nathan.mills@gmail.com>
8/19
----
lib/readline/isearch.c
- _rl_isearch_cleanup: to avoid problems caused by calling this from
normal isearch termination and from signal cleanup code, turn off
the RL_STATE_ISEARCH flag and set _rl_iscxt to NULL before doing
anything else that would cause signals to be processed.
Report and fix from Grisha Levit <grishalevit@gmail.com> based on
a report from penguin p <tgckpg@gmail.com>
+1 -1
View File
@@ -942,7 +942,7 @@ examples/shellmath/testCases.in f
examples/shellmath/timingData.txt f
tests/README f
tests/COPYRIGHT f
tests/test-glue-functions f
tests/test-aux-functions f
tests/alias.tests f
tests/alias1.sub f
tests/alias2.sub f
+2
View File
@@ -102,6 +102,7 @@ convert_var_to_array (SHELL_VAR *var)
/* Since namerefs can't be array variables, turn off nameref attribute */
VUNSETATTR (var, att_nameref);
stupidly_hack_special_variables (var->name);
return var;
}
@@ -139,6 +140,7 @@ convert_var_to_assoc (SHELL_VAR *var)
/* Since namerefs can't be array variables, turn off nameref attribute */
VUNSETATTR (var, att_nameref);
stupidly_hack_special_variables (var->name);
return var;
}
+1 -1
View File
@@ -4156,7 +4156,7 @@ bind_lastarg (char *arg)
if (arg == 0)
arg = "";
var = bind_variable ("_", arg, 0);
var = bind_variable ("_", arg, ASS_NOTEMPENV);
if (var)
VUNSETATTR (var, att_exported);
}
+5 -3
View File
@@ -889,12 +889,14 @@ opcode_dispatch:
int
_rl_isearch_cleanup (_rl_search_cxt *cxt, int r)
{
RL_UNSETSTATE(RL_STATE_ISEARCH);
if (cxt == 0)
return (r != 0);
_rl_iscxt = 0;
if (r >= 0)
_rl_isearch_fini (cxt);
_rl_scxt_dispose (cxt, 0);
_rl_iscxt = 0;
RL_UNSETSTATE(RL_STATE_ISEARCH);
return (r != 0);
}
+2
View File
@@ -446,8 +446,10 @@ extern void _rl_signal_handler (int);
extern void _rl_block_sigint (void);
extern void _rl_release_sigint (void);
extern int _rl_sigint_blocked_p (void);
extern void _rl_block_sigwinch (void);
extern void _rl_release_sigwinch (void);
extern int _rl_sigwinch_blocked_p (void);
extern void _rl_state_sigcleanup (void);
+12
View File
@@ -680,6 +680,12 @@ _rl_release_sigint (void)
RL_CHECK_SIGNALS ();
}
int
_rl_sigint_blocked_p (void)
{
return sigint_blocked;
}
/* Cause SIGWINCH to not be delivered until the corresponding call to
release_sigwinch(). */
void
@@ -736,6 +742,12 @@ _rl_release_sigwinch (void)
sigwinch_blocked = 0;
}
int
_rl_sigwinch_blocked_p (void)
{
return sigwinch_blocked;
}
/* **************************************************************** */
/* */
/* Echoing special control characters */
+22 -3
View File
@@ -2500,6 +2500,8 @@ shell_getc (int remove_quoted_newline)
something on the pushed list of strings, then we don't want to go
off and get another line. We let the code down below handle it. */
/* If we're reading input from the keyboard or from a file, fetch
another line from the current source. */
if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
(pushed_string_list == (STRING_SAVER *)NULL)))
#else /* !ALIAS && !DPAREN_ARITHMETIC */
@@ -2741,11 +2743,11 @@ shell_getc (int remove_quoted_newline)
going to be removing quoted newlines, since that will eat the
backslash. Add another backslash instead (will be removed by
word expansion). */
if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
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)
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)
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';
@@ -2905,6 +2907,18 @@ pop_alias:
shell_input_line_index = 0;
goto restart_read;
}
#if 0 /*TAG:bash-5.4 wyeth2485@gmail.com 8/15/2025 */
/* When we're reading input from a string, we don't increment line_number
until now. If we're being called from read_token_word(), this will be
pushed back into the input string with shell_ungetc for the next call
to read_token() to consume. We don't want to increment line_number
twice, so this requires cooperation from shell_ungetc (decrement
line_number if we're pushing back a newline while parsing an alias
expansion). */
if (uc == '\n' && expanding_alias () && pushed_string_list->flags == PSH_ALIAS)
line_number++;
#endif
#endif
return (uc);
@@ -2922,6 +2936,11 @@ shell_ungetc (int c)
shell_input_line[--shell_input_line_index] = c;
else
eol_ungetc_lookahead = c;
#if 0 /*TAG:bash-5.4 wyeth2485@gmail.com 8/15/2025 */
if (c == '\n' && expanding_alias () && heredoc_string == 0 && line_number > 0)
line_number--;
#endif
}
/* Push S back into shell_input_line; updating shell_input_line_index */
+14 -3
View File
@@ -206,6 +206,8 @@ extern int wordexp_only;
extern int singlequote_translations;
extern int extended_quote;
extern REDIRECT *exec_redirection_undo_list, *redirection_undo_list;
#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
extern wchar_t *wcsdup (const wchar_t *);
#endif
@@ -7022,7 +7024,12 @@ function_substitute (char *string, int quoted, int flags)
add_unwind_protect (uw_restore_pipestatus_array, psa);
}
#endif
unwind_protect_pointer (redirection_undo_list);
redirection_undo_list = NULL;
unwind_protect_pointer (exec_redirection_undo_list);
exec_redirection_undo_list = NULL;
subst_assign_varlist = 0;
temporary_env = 0;
@@ -12358,11 +12365,15 @@ word_list_quote_removal (WORD_LIST *list, int quoted)
void
setifs (SHELL_VAR *v)
{
char *t;
char *t, *value;
unsigned char uc;
ifs_var = v;
ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
/* If we do not want to support IFS as an array variable here, check that
V is not an array (array_p(v) == 0 && assoc_p (v) == 0) as part of the
test to call get_variable_value and set VALUE to NULL if it is. */
value = v ? get_variable_value (v) : (char *)NULL;
ifs_value = (v && value) ? value : " \t\n";
ifs_is_set = ifs_var != 0;
ifs_is_null = ifs_is_set && (*ifs_value == 0);
+1 -1
View File
@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
. ./test-glue-functions
. ./test-aux-functions
# this locale causes problems all over the place
if locale -a | grep -i '^zh_TW\.big5' >/dev/null ; then
+1 -1
View File
@@ -12,7 +12,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test history file truncation for various values of $HISTFILESIZE
. ./test-glue-functions
. ./test-aux-functions
: ${THIS_SH:=./bash}
: ${TMPDIR:=/var/tmp}
+1 -1
View File
@@ -49,7 +49,7 @@ set a b
printf '%s\n' "$*"
. ./test-glue-functions
. ./test-aux-functions
printf '%s' "$*" | od -b | _intl_normalize_spaces
+1 -1
View File
@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
. ./test-glue-functions
. ./test-aux-functions
# more tests to make sure that IFS splits on characters, not bytes
export LANG=en_US.UTF-8
+1
View File
@@ -534,6 +534,7 @@ declare -a array=([0]="one" [1]="two" [2]="three")
declare -ai a=([0]="5")
declare -ai a=([0]="6")
declare -ai a=([0]="42")
./nameref23.sub: line 28: declare: a[0]: expands to invalid variable name for name reference
declare -ai a=([0]="1")
./nameref23.sub: line 29: declare: b: not found
declare -ai a=([0]="1")
+1 -1
View File
@@ -1,4 +1,4 @@
. ./test-glue-functions
. ./test-aux-functions
recho $'\c?'
+1 -1
View File
@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
. test-glue-functions
. test-aux-functions
recho $( echo a$'\01)'b )
recho $( echo ab )
+1 -1
View File
@@ -58,6 +58,6 @@ time -p -- echo a
time -- :
# this should print timing information
. ./test-glue-functions
. ./test-aux-functions
${THIS_SH} -c '{ time; echo after; }' |& wc -l | _cut_leading_spaces
+1 -1
View File
@@ -12,7 +12,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# process substitution constructs that have caused problems in the past
. ./test-glue-functions
. ./test-aux-functions
eval cat <(echo test1)
eval "echo foo;cat" <(echo test2)
+21
View File
@@ -0,0 +1,21 @@
# shell functions to include in multiple test files
# squeeze out blanks to avoid white space differences in od implementations
_intl_normalize_spaces()
{
sed -e 's/[[:space:]]\{1,\}/ /g' -e 's/[[:space:]]*$//'
}
# avoid whitespace differences in wc implementations
_cut_leading_spaces()
{
sed -e 's/^[ ]*//g'
}
test_runsub()
{
scriptname=${1##*/}
printf '\t%s\n' "${scriptname}"
${THIS_SH} "$1"
}
+1 -1
View File
@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
. ./test-glue-functions
. ./test-aux-functions
export LANG=en_US.UTF-8
+2
View File
@@ -173,6 +173,8 @@ typedef struct _vlist {
#define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
#define propagate_p(var) ((((var)->attributes) & (att_propagate)))
#define assigning_p(var) ((((var)->attributes) & (att_assigning)))
/* Variable names: lvalues */
#define name_cell(var) ((var)->name)