mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-11-11 00:53:52 +01:00
fix to make verbose mode print lines as they're read while parsing a multi-line command substitution; change to readline so that it no longer treats SIGTERM causing an immediate exit, so bash can trap it in interactive shells; fix potential integer overflow on command substitution output larger than 2GB; make trap action execution ignore any current break and continue conditions, so actions are always executed even if break or continue was executed before the trap was handled
This commit is contained in:
1 parent
7cfdb340d2
commit
5e427bb15d
10 files changed
+93
-21
No files matched your search
+1
-1
@@ -635,7 +635,7 @@ jj. Asynchronous commands now always set $? to 0 and are not affected by
|
||||
whether or not the command's exit status is being inverted.
|
||||
|
||||
kk. Fixed a problem that caused a line ending with an escaped newline and
|
||||
containingh a prior `eval' to be incorrectly parsed.
|
||||
containing a prior `eval' to be incorrectly parsed.
|
||||
|
||||
ll. Fixed an issue with programmable completion and `!' in extglob patterns
|
||||
used as arguments to `compgen -X'.
|
||||
|
||||
+2
-1
@@ -503,7 +503,8 @@ j. shell-transpose-words: a new bindable readline command that uses the same
|
||||
k. The shell now adds default bindings for shell-forward-word,
|
||||
shell-backward-word, shell-transpose-words, and shell-kill-word.
|
||||
|
||||
l. Bash now allows ARGV0 appearing in the initial shell environment to set $0.
|
||||
l. Bash now allows BASH_ARGV0 appearing in the initial shell environment to
|
||||
set $0.
|
||||
|
||||
m. If `unset' is executed without option arguments, bash tries to unset a shell
|
||||
function if a name argument cannot be a shell variable name because it's not
|
||||
|
||||
+1
-1
@@ -534,7 +534,7 @@ dddd. Work around system-specific problems (macOS) where isblank(3) returns
|
||||
eeee. Fix for crash while parsing alias expansions that include compound
|
||||
assignments.
|
||||
|
||||
ffff. Fixe for non-interactive shells reading a script file that ends with
|
||||
ffff. Fix for non-interactive shells reading a script file that ends with
|
||||
backslash preceding EOF.
|
||||
|
||||
gggg. Fix to command printing when here-documents are attached to compound
|
||||
|
||||
@@ -13430,3 +13430,38 @@ error.c
|
||||
the `exec' builtin, since the `execfail' shopt is supposed to
|
||||
inhibit this.
|
||||
Report from Zev Weiss <zev@bewilderbeest.net>
|
||||
|
||||
10/5
|
||||
----
|
||||
parse.y
|
||||
- xparse_dolparen: turn off echo_input_at_read so we don't echo lines
|
||||
a second time
|
||||
- shell_getc: if echo_input_at_read is on, echo input lines even if
|
||||
shell_eof_token is `)' or `}'; rely on the callers to make sure it's
|
||||
off if not wanted (e.g., by xparse_dolparen)
|
||||
From https://savannah.gnu.org/bugs/?68735
|
||||
|
||||
10/13
|
||||
-----
|
||||
lib/readline/input.c
|
||||
- rl_getc: handle receipt of SIGTERM while waiting for input like a
|
||||
SIGINT (call RL_CHECK_SIGNALS()) instead of SIGHUP. Might need to
|
||||
explicitly return error/EOF if the application's signal handler is
|
||||
SIG_IGN for backwards compatibility.
|
||||
From a report by Denys Vlasenko <dvlasenk@redhat.com>
|
||||
|
||||
10/14
|
||||
-----
|
||||
stringlib.c,externs.h
|
||||
- strip_trailing: LEN argument is now size_t to avoid integer overflow
|
||||
on command substitution strings longer than 2GB
|
||||
Report from Lilian CRIMET <lilian.crimet@gmail.com>
|
||||
|
||||
10/22
|
||||
-----
|
||||
trap.c
|
||||
- run_pending_traps, _run_trap_internal: make sure to set breaking
|
||||
and continuing to 0 before running the trap action, then restore
|
||||
them after the action completes. Make sure to handle the case where
|
||||
the trap action runs break or continue.
|
||||
From a report by Dimitrios Christou <dimitrios.christou@skillonnet.com>
|
||||
+1
-2
@@ -4394,7 +4394,7 @@ exec [-cl] [-a @var{name}] [@var{command} [@var{arguments}]]
|
||||
If @var{command}
|
||||
is supplied, it replaces the shell without creating a new process.
|
||||
@var{command} cannot be a shell builtin or function.
|
||||
The @var{arguments} become the arguments to @var{command}
|
||||
The @var{arguments} become the arguments to @var{command}.
|
||||
If the @option{-l} option is supplied, the shell places a dash at the
|
||||
beginning of the zeroth argument passed to @var{command}.
|
||||
This is what the @code{login} program does.
|
||||
@@ -9202,7 +9202,6 @@ Readline,
|
||||
and is ignored and removed otherwise,
|
||||
so it shouldn't be used in @env{PS0} or @env{PS4},
|
||||
or when line editing is not enabled.
|
||||
|
||||
@item \]
|
||||
End a sequence of non-printing characters begun with @samp{\[}
|
||||
@end table
|
||||
|
||||
@@ -174,7 +174,7 @@ extern char *substring (const char *, size_t, size_t);
|
||||
extern char *strsub (const char *, const char *, const char *, int);
|
||||
extern char *strcreplace (const char *, int, const char *, int);
|
||||
extern void strip_leading (char *);
|
||||
extern void strip_trailing (char *, int, int);
|
||||
extern void strip_trailing (char *, size_t, int);
|
||||
extern int str_firstdiff (const char *, const char *);
|
||||
extern int str_lastsame (const char *, const char *);
|
||||
|
||||
|
||||
+10
-6
@@ -958,18 +958,22 @@ rl_getc (FILE *stream)
|
||||
/* If the error that we received was EINTR, then try again,
|
||||
this is simply an interrupted system call to read (). We allow
|
||||
the read to be interrupted if we caught SIGHUP, SIGTERM, or any
|
||||
of the other signals readline treats specially. If the
|
||||
application sets an event hook, call it for other signals.
|
||||
of the other signals readline treats specially. SIGHUP causes an
|
||||
immediate error/EOF return; the other signals call back to the
|
||||
application through RL_CHECK_SIGNALS.
|
||||
If the application sets an event hook, call it for other signals.
|
||||
Otherwise (not EINTR), some error occurred, also signifying EOF. */
|
||||
if (errno != EINTR)
|
||||
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
|
||||
/* fatal signals of interest */
|
||||
#if defined (SIGHUP)
|
||||
else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
|
||||
#else
|
||||
else if (_rl_caught_signal == SIGTERM)
|
||||
#endif
|
||||
else if (_rl_caught_signal == SIGHUP)
|
||||
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
|
||||
#endif
|
||||
else if (_rl_caught_signal == SIGTERM)
|
||||
/* Allow the application to handle or exit instead of error/EOF */
|
||||
RL_CHECK_SIGNALS ();
|
||||
|
||||
/* keyboard-generated signals of interest */
|
||||
#if defined (SIGQUIT)
|
||||
else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
|
||||
|
||||
@@ -453,7 +453,7 @@ inputunit: simple_list simple_list_terminator
|
||||
| funsub
|
||||
{
|
||||
/* This is special; look at the production and how
|
||||
parse_comsub/parse_valsub sets token_to_read */
|
||||
parse_comsub sets token_to_read */
|
||||
global_command = $1;
|
||||
YYACCEPT;
|
||||
}
|
||||
@@ -2713,15 +2713,18 @@ shell_getc (int remove_quoted_newline)
|
||||
if (shell_input_line)
|
||||
{
|
||||
/* Lines that signify the end of the shell's input should not be
|
||||
echoed. We should not echo lines while parsing command
|
||||
substitutions with recursive calls into the parsing engine; those
|
||||
should only be echoed once when we read the word. That is the
|
||||
reason for the test against shell_eof_token, which is set to a
|
||||
right paren when parsing the contents of command substitutions. */
|
||||
echoed. We should echo lines while parsing command and process
|
||||
substitutions only once: the first time parse_comsub() is called.
|
||||
Further calls via xparse_dolparen or during parse_and_execute
|
||||
should not result in echoing input; we rely on the callers to
|
||||
set echo_input_at_read appropriately. That is the reason for the
|
||||
test against shell_eof_token, which is probably more elaborate
|
||||
than is really necessary. */
|
||||
if (echo_input_at_read && (shell_input_line[0] ||
|
||||
(shell_input_line_terminator != EOF &&
|
||||
shell_input_line_terminator != READERR)) &&
|
||||
shell_eof_token == 0)
|
||||
/*(*/ (shell_eof_token == 0 ||
|
||||
((parser_state & PST_EOFTOKEN) && shell_eof_token == ')' || shell_eof_token == '}')))
|
||||
fprintf (stderr, "%s\n", shell_input_line);
|
||||
}
|
||||
else
|
||||
@@ -4766,6 +4769,10 @@ xparse_dolparen (const char *base, char *string, size_t *indp, int flags)
|
||||
local_extglob = extended_glob;
|
||||
#endif
|
||||
|
||||
/* We also choose not to echo input at this stage; if verbose is on, the
|
||||
first call to parse_comsub should echo the input lines. */
|
||||
echo_input_at_read = 0;
|
||||
|
||||
if (funsub && FUNSUB_CHAR (*string) && (*string == '|' || *string == ';'))
|
||||
string++;
|
||||
|
||||
@@ -4787,6 +4794,7 @@ xparse_dolparen (const char *base, char *string, size_t *indp, int flags)
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extended_glob = local_extglob;
|
||||
#endif
|
||||
echo_input_at_read = verbose_flag;
|
||||
token_to_read = 0;
|
||||
|
||||
simplecmd_lineno = save_lineno;
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ strip_leading (char *string)
|
||||
newlines. If NEWLINES_ONLY is non-zero, only trailing newlines
|
||||
are removed. STRING should be terminated with a zero. */
|
||||
void
|
||||
strip_trailing (char *string, int len, int newlines_only)
|
||||
strip_trailing (char *string, size_t len, int newlines_only)
|
||||
{
|
||||
while (len >= 0)
|
||||
{
|
||||
|
||||
@@ -332,6 +332,7 @@ run_pending_traps (void)
|
||||
register int sig;
|
||||
int x;
|
||||
volatile int old_exit_value, old_running, old_context;
|
||||
volatile int old_breaking, old_continuing;
|
||||
WORD_LIST *save_subst_varlist;
|
||||
HASH_TABLE *save_tempenv;
|
||||
sh_parser_state_t pstate;
|
||||
@@ -485,6 +486,10 @@ run_pending_traps (void)
|
||||
pending_traps[sig] = 0;
|
||||
evalnest++;
|
||||
|
||||
old_breaking = breaking;
|
||||
old_continuing = continuing;
|
||||
breaking = continuing = 0;
|
||||
|
||||
function_code = 0;
|
||||
save_return_catch_flag = return_catch_flag;
|
||||
if (return_catch_flag)
|
||||
@@ -507,6 +512,12 @@ run_pending_traps (void)
|
||||
x = return_catch_value;
|
||||
}
|
||||
|
||||
/* what if the trap command runs `break' or `continue'? */
|
||||
if (breaking == 0 || old_breaking != 0)
|
||||
breaking = old_breaking;
|
||||
if (continuing == 0 || old_continuing != 0)
|
||||
continuing = old_continuing;
|
||||
|
||||
evalnest--;
|
||||
#if defined (JOB_CONTROL)
|
||||
restore_pipeline (1);
|
||||
@@ -1074,6 +1085,7 @@ run_exit_trap (void)
|
||||
pflags = interactive_shell ? SEVAL_NOTIFY : 0;
|
||||
pflags |= SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE;
|
||||
reset_parser ();
|
||||
breaking = continuing = 0;
|
||||
parse_and_execute (trap_command, "exit trap", pflags);
|
||||
}
|
||||
else if (code == ERREXIT)
|
||||
@@ -1133,7 +1145,9 @@ _run_trap_internal (int sig, char *tag)
|
||||
char *old_trapsig;
|
||||
int trap_exit_value;
|
||||
volatile int save_return_catch_flag, function_code;
|
||||
int old_modes, old_running, old_int, old_context;
|
||||
volatile int old_running, old_int, old_context;
|
||||
volatile int old_breaking, old_continuing;
|
||||
int old_modes;
|
||||
int flags;
|
||||
procenv_t save_return_catch;
|
||||
WORD_LIST *save_subst_varlist;
|
||||
@@ -1204,6 +1218,10 @@ _run_trap_internal (int sig, char *tag)
|
||||
/* XXX - set pending_traps[sig] = 0 here? */
|
||||
evalnest++;
|
||||
|
||||
old_breaking = breaking;
|
||||
old_continuing = continuing;
|
||||
breaking = continuing = 0;
|
||||
|
||||
/* If we're in a function, make sure return longjmps come here, too. */
|
||||
function_code = 0;
|
||||
save_return_catch_flag = return_catch_flag;
|
||||
@@ -1225,6 +1243,13 @@ _run_trap_internal (int sig, char *tag)
|
||||
}
|
||||
else
|
||||
trap_exit_value = return_catch_value;
|
||||
|
||||
/* what if the trap command runs `break' or `continue'? */
|
||||
if (breaking == 0 || old_breaking != 0)
|
||||
breaking = old_breaking;
|
||||
if (continuing == 0 || old_continuing != 0)
|
||||
continuing = old_continuing;
|
||||
|
||||
evalnest--;
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
|
||||
Reference in new issue
Block a user