summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2016-11-10 11:32:12 -0500
committerChet Ramey <chet.ramey@case.edu>2016-11-10 11:32:12 -0500
commit78a3f8a4bae8ef98daa26b64ddbc03c6fc3ffcd0 (patch)
tree18a0ee4f8546d38f23f334afc65956fd3a108c07
parentec1101c37ea25a61db37c268f736089061c9afaa (diff)
downloadbash-78a3f8a4bae8ef98daa26b64ddbc03c6fc3ffcd0.tar.gz
commit bash-20161108 snapshot
-rw-r--r--CWRU/CWRU.chlog91
-rw-r--r--builtins/common.c4
-rw-r--r--builtins/evalstring.c5
-rw-r--r--builtins/read.def8
-rw-r--r--builtins/trap.def4
-rw-r--r--eval.c2
-rw-r--r--execute_cmd.c29
-rw-r--r--expr.c15
-rw-r--r--lib/sh/unicode.c6
-rw-r--r--nojobs.c10
-rw-r--r--subst.c123
-rw-r--r--test.c8
-rw-r--r--trap.c2
13 files changed, 219 insertions, 88 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog
index 289c8e5..0ea6410 100644
--- a/CWRU/CWRU.chlog
+++ b/CWRU/CWRU.chlog
@@ -12008,7 +12008,7 @@ aclocal.m4
-----
variables.c
- get_bashpid: BASHPID is no longer readonly; assignments to it are
- just ignored. Suggested by Martijn Dekker <martijn@inlv.org>
+ just ignored.
doc/{bash.1,bashref.texi}
- BASHPID: note that assignments are ignored and unsetting BASHPID
@@ -12199,3 +12199,92 @@ lib/glob/sm_loop.c
- GMATCH: allow trailing backslash in pattern to explicitly match a
backslash that is the last character in the string. Bug report from
Stephane Chazelas <stephane.chazelas@gmail.com>
+
+ 11/5
+ ----
+builtins/common.c
+ - display_signal_list: if displaying a signal name corresponding to an
+ exit status > 128, don't display the SIG prefix at all. Old code
+ made displaying the SIG prefix dependent on JOB_CONTROL define.
+ Report and fix from Martijn Dekker <martijn@inlv.org>
+
+execute_cmd.c
+ - execute_subshell_builtin_or_function: call without_job_control even
+ if JOB_CONTROL is not defined. Similar to fix from 9/23.
+ Report from Martijn Dekker <martijn@inlv.org>
+
+execute_cmd.c
+ - execute_simple_command: free memory allocated and passed to
+ make_child in the child process if JOB_CONTROL is defined
+ - execute_command_internal: free memory allocated and passed to
+ make_child in the child process created to run a () subshell or a
+ compound command within a pipeline if JOB_CONTROL is defined
+ - execute_coproc: free memory allocated and passed to make_child in
+ the child process if JOB_CONTROL is defined
+ - execute_disk_command: free memory allocated and passed to
+ make_child in the child process if JOB_CONTROL is defined. This
+ series of fixes is the result of reports from
+ Eduardo A. Bustamante López <dualbus@gmail.com>
+
+ 11/6
+ ----
+lib/sh/unicode.c
+ - u32toutf16: fix to prevent outputting broken surrogate pairs for
+ Japanese locales (ja_JP.UTF-8) on cygwin (which uses UTF-16 natively).
+ Report and fix from Koichi MURASE <myoga.murase@gmail.com>
+
+builtins/trap.def
+ - trap_builtin: if OP is `-' (revert), set the SIGINT signal handler
+ to sigint_sighandler if the shell is interactive and sourcing a
+ file (interactive_shell && sourcelevel) or running a trap
+ (interactive_shell && running_trap) even if it's not currently
+ interactive. Report from Martijn Dekker <martijn@inlv.org>
+
+builtins/read.def
+ - check for and read multibyte characters in all cases, not just when
+ we are reading a specific number of characters, as long as
+ mb_cur_max > 1
+
+subst.c
+ - expand_word_internal: some improvements to code that converts istring
+ into a WORD_LIST * to avoid multiple allocations and copies of
+ istring, which is already malloc'ed memory -- reduce number of malloc
+ and free calls
+
+test.c
+ - unary_test: make sure if we test -v array[@] or array[*] that we
+ free the return value from array_value
+
+ 11/8
+ ----
+expr.c
+ - expcond: make sure to set `noeval' before reading tokens depending on
+ the result of the conditional test, since readtok() can evaluate
+ identifiers (and recursively those containing expressions). Report
+ and fix from Koichi MURASE <myoga.murase@gmail.com>
+
+builtins/evalstring.c
+ - should_suppress_fork: make sure to check for traps on EXIT and
+ ERR, since any_signals_trapped() only checks for `real' signals,
+ not the fake shell ones. Fixes bug reported by Werner Fink
+ <werner@suse.de>
+ - optimize_subshell_command: ditto
+
+ 11/9
+ ----
+eval.c
+ - reader_loop: change so that we don't reset the SIGINT handler every
+ time through the command loop in an interactive shell if the signal
+ is trapped (as the comment noted). Reported by Report from Martijn
+ Dekker <martijn@inlv.org>
+
+subst.c
+ - parameter_brace_{patsub,remove_pattern,transform,casemod}: save and
+ restore this_command_name while temporarily setting it for use in
+ error messages. Fixes use-after-free error reported by
+ op7ic \x00 <op7ica@gmail.com>
+ - string_extract_verbatim: make sure when we increment i by 2 due to
+ a CTLESC or CTLESC-CTLNUL that we don't read past the end of the
+ string. This can happen if the string ends with an odd number of
+ CTLESC chars. Fixes oob-read error reported by
+ op7ic \x00 <op7ica@gmail.com>
diff --git a/builtins/common.c b/builtins/common.c
index 0eabe06..9e06c1e 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -782,13 +782,9 @@ display_signal_list (list, forcecols)
list = list->next;
continue;
}
-#if defined (JOB_CONTROL)
/* POSIX.2 says that `kill -l signum' prints the signal name without
the `SIG' prefix. */
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
-#else
- printf ("%s\n", name);
-#endif
}
else
{
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index 7e1487e..f258bd1 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -104,12 +104,9 @@ should_suppress_fork (command)
running_trap == 0 &&
*bash_input.location.string == '\0' &&
command->type == cm_simple &&
-#if 0
signal_is_trapped (EXIT_TRAP) == 0 &&
signal_is_trapped (ERROR_TRAP) == 0 &&
-#else
any_signals_trapped () < 0 &&
-#endif
command->redirects == 0 && command->value.Simple->redirects == 0 &&
((command->flags & CMD_TIME_PIPELINE) == 0) &&
((command->flags & CMD_INVERT_RETURN) == 0));
@@ -134,6 +131,8 @@ optimize_subshell_command (command)
{
if (running_trap == 0 &&
command->type == cm_simple &&
+ signal_is_trapped (EXIT_TRAP) == 0 &&
+ signal_is_trapped (ERROR_TRAP) == 0 &&
any_signals_trapped () < 0 &&
command->redirects == 0 && command->value.Simple->redirects == 0 &&
((command->flags & CMD_TIME_PIPELINE) == 0) &&
diff --git a/builtins/read.def b/builtins/read.def
index ce5e9ff..a7f80b3 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -181,6 +181,7 @@ read_builtin (list)
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno;
+ int mb_cur_max;
unsigned int tmsec, tmusec;
long ival, uval;
intmax_t intval;
@@ -235,6 +236,7 @@ read_builtin (list)
rlind = 0;
#endif
+ mb_cur_max = MB_CUR_MAX;
tmsec = tmusec = 0; /* no timeout */
nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
delim = '\n'; /* read until newline */
@@ -664,7 +666,11 @@ add_char:
CHECK_ALRM;
#if defined (HANDLE_MULTIBYTE)
- if (nchars > 0 && MB_CUR_MAX > 1 && is_basic (c) == 0)
+# if 0
+ if (nchars > 0 && mb_cur_max > 1 && is_basic (c) == 0)
+# else
+ if (mb_cur_max > 1 && is_basic (c) == 0)
+# endif
{
input_string[i] = '\0'; /* for simplicity and debugging */
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
diff --git a/builtins/trap.def b/builtins/trap.def
index 57d9b52..d43b0ef 100644
--- a/builtins/trap.def
+++ b/builtins/trap.def
@@ -98,6 +98,7 @@ static int display_traps __P((WORD_LIST *));
#define IGNORE 2 /* Ignore this signal. */
extern int posixly_correct, subshell_environment;
+extern int sourcelevel, running_trap;
int
trap_builtin (list)
@@ -212,6 +213,9 @@ trap_builtin (list)
was SIG_IGN? */
if (interactive)
set_signal_handler (SIGINT, sigint_sighandler);
+ /* special cases for interactive == 0 */
+ else if (interactive_shell && (sourcelevel||running_trap))
+ set_signal_handler (SIGINT, sigint_sighandler);
else
set_signal_handler (SIGINT, termsig_sighandler);
break;
diff --git a/eval.c b/eval.c
index db863e7..db53946 100644
--- a/eval.c
+++ b/eval.c
@@ -90,7 +90,7 @@ reader_loop ()
/* XXX - why do we set this every time through the loop? And why do
it if SIGINT is trapped in an interactive shell? */
- if (interactive_shell && signal_is_ignored (SIGINT) == 0)
+ if (interactive_shell && signal_is_ignored (SIGINT) == 0 && signal_is_trapped (SIGINT) == 0)
set_signal_handler (SIGINT, sigint_sighandler);
if (code != NOT_JUMPED)
diff --git a/execute_cmd.c b/execute_cmd.c
index b2f0dbc..a148ba4 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -602,12 +602,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
{
pid_t paren_pid;
int s;
+ char *p;
/* Fork a subshell, turn off the subshell bit, turn off job
control and call execute_command () on the command again. */
line_number_for_err_trap = line_number; /* XXX - save value? */
tcmd = make_command_string (command);
- paren_pid = make_child (savestring (tcmd), asynchronous);
+ paren_pid = make_child (p = savestring (tcmd), asynchronous);
if (user_subshell && signal_is_trapped (ERROR_TRAP) &&
signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
@@ -618,6 +619,9 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
if (paren_pid == 0)
{
+#if defined (JOB_CONTROL)
+ FREE (p); /* child doesn't use pointer */
+#endif
/* We want to run the exit trap for forced {} subshells, and we
want to note this before execute_in_subshell modifies the
COMMAND struct. Need to keep in mind that execute_in_subshell
@@ -2279,7 +2283,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
int rpipe[2], wpipe[2], estat, invert;
pid_t coproc_pid;
Coproc *cp;
- char *tcmd;
+ char *tcmd, *p;
sigset_t set, oset;
/* XXX -- can be removed after changes to handle multiple coprocs */
@@ -2298,13 +2302,17 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
BLOCK_SIGNAL (SIGCHLD, set, oset);
- coproc_pid = make_child (savestring (tcmd), 1);
+ coproc_pid = make_child (p = savestring (tcmd), 1);
if (coproc_pid == 0)
{
close (rpipe[0]);
close (wpipe[1]);
+#if defined (JOB_CONTROL)
+ FREE (p);
+#endif
+
UNBLOCK_SIGNAL (oset);
estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close);
@@ -4138,7 +4146,9 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
if (async)
subshell_level++; /* not for pipes yet */
-FREE (p);
+#if defined (JOB_CONTROL)
+ FREE (p); /* child doesn't use pointer */
+#endif
}
else
{
@@ -4936,6 +4946,8 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
without_job_control ();
set_sigchld_handler ();
+#else
+ without_job_control ();
#endif /* JOB_CONTROL */
set_sigint_handler ();
@@ -5166,7 +5178,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
struct fd_bitmap *fds_to_close;
int cmdflags;
{
- char *pathname, *command, **args;
+ char *pathname, *command, **args, *p;
int nofork, stdpath, result;
pid_t pid;
SHELL_VAR *hookf;
@@ -5176,6 +5188,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */
pathname = words->word->word;
+ p = 0;
result = EXECUTION_SUCCESS;
#if defined (RESTRICTED_SHELL)
command = (char *)NULL;
@@ -5214,7 +5227,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
pid = 0;
else
- pid = make_child (savestring (command_line), async);
+ pid = make_child (p = savestring (command_line), async);
if (pid == 0)
{
@@ -5226,6 +5239,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
CHECK_SIGTERM;
+#if defined (JOB_CONTROL)
+ FREE (p);
+#endif
+
/* restore_original_signals may have undone the work done
by make_child to ensure that SIGINT and SIGQUIT are ignored
in asynchronous children. */
diff --git a/expr.c b/expr.c
index dcea480..38a355a 100644
--- a/expr.c
+++ b/expr.c
@@ -578,24 +578,23 @@ expcond ()
rval = cval = explor ();
if (curtok == QUES) /* found conditional expr */
{
- readtok ();
- if (curtok == 0 || curtok == COL)
- evalerror (_("expression expected"));
if (cval == 0)
{
set_noeval = 1;
noeval++;
}
+ readtok ();
+ if (curtok == 0 || curtok == COL)
+ evalerror (_("expression expected"));
+
val1 = EXP_HIGHEST ();
if (set_noeval)
noeval--;
if (curtok != COL)
evalerror (_("`:' expected for conditional expression"));
- readtok ();
- if (curtok == 0)
- evalerror (_("expression expected"));
+
set_noeval = 0;
if (cval)
{
@@ -603,7 +602,11 @@ expcond ()
noeval++;
}
+ readtok ();
+ if (curtok == 0)
+ evalerror (_("expression expected"));
val2 = expcond ();
+
if (set_noeval)
noeval--;
rval = cval ? val1 : val2;
diff --git a/lib/sh/unicode.c b/lib/sh/unicode.c
index b58eaef..79e91a6 100644
--- a/lib/sh/unicode.c
+++ b/lib/sh/unicode.c
@@ -1,6 +1,6 @@
/* unicode.c - functions to convert unicode characters */
-/* Copyright (C) 2010-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2010-2016 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -219,12 +219,12 @@ u32toutf16 (c, s)
int l;
l = 0;
- if (c < 0x0d800)
+ if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff))
{
s[0] = (unsigned short) (c & 0xFFFF);
l = 1;
}
- else if (c >= 0x0e000 && c <= 0x010ffff)
+ else if (c >= 0x10000 && c <= 0x010ffff)
{
c -= 0x010000;
s[0] = (unsigned short)((c >> 10) + 0xd800);
diff --git a/nojobs.c b/nojobs.c
index fdbe0ae..b1b995e 100644
--- a/nojobs.c
+++ b/nojobs.c
@@ -170,7 +170,10 @@ alloc_pid_list ()
/* None of the newly allocated slots have process id's yet. */
for (i = old; i < pid_list_size; i++)
- pid_list[i].pid = NO_PID;
+ {
+ pid_list[i].pid = NO_PID;
+ pid_list[i].status = pid_list[i].flags = 0;
+ }
}
/* Return the offset within the PID_LIST array of an empty slot. This can
@@ -399,8 +402,9 @@ cleanup_dead_jobs ()
for (i = 0; i < pid_list_size; i++)
{
- if ((pid_list[i].flags & PROC_RUNNING) == 0 &&
- (pid_list[i].flags & PROC_NOTIFIED))
+ if (pid_list[i].pid != NO_PID &&
+ (pid_list[i].flags & PROC_RUNNING) == 0 &&
+ (pid_list[i].flags & PROC_NOTIFIED))
pid_list[i].pid = NO_PID;
}
diff --git a/subst.c b/subst.c
index 0cee56f..7187b3b 100644
--- a/subst.c
+++ b/subst.c
@@ -1166,6 +1166,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
{
i += 2;
+ CHECK_STRING_OVERRUN (i, i, slen, c);
continue;
}
/* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
@@ -1174,6 +1175,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
{
i += 2;
+ CHECK_STRING_OVERRUN (i, i, slen, c);
continue;
}
@@ -2773,11 +2775,11 @@ list_string (string, separators, quoted)
extract a word, stopping at a separator
skip sequences of spc, tab, or nl as long as they are separators
This obeys the field splitting rules in Posix.2. */
- slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 1;
+ slen = STRLEN (string);
for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
{
- /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
- unless multibyte chars are possible. */
+ /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
+ possible, but need it in string_extract_verbatim for bounds checking */
current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
if (current_word == 0)
break;
@@ -2902,9 +2904,9 @@ get_word_from_string (stringp, separators, endptr)
This obeys the field splitting rules in Posix.2. */
sindex = 0;
- /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
- unless multibyte chars are possible. */
- slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1;
+ /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
+ possible, but need it in string_extract_verbatim for bounds checking */
+ slen = STRLEN (s);
current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
/* Set ENDPTR to the first character after the end of the word. */
@@ -5015,17 +5017,21 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
int rtype, quoted, flags;
{
int vtype, patspec, starsub;
- char *temp1, *val, *pattern;
+ char *temp1, *val, *pattern, *oname;
SHELL_VAR *v;
if (value == 0)
return ((char *)NULL);
+ oname = this_command_name;
this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1)
- return ((char *)NULL);
+ {
+ this_command_name = oname;
+ return ((char *)NULL);
+ }
starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB;
@@ -5079,6 +5085,8 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
break;
}
+ this_command_name = oname;
+
FREE (pattern);
return temp1;
}
@@ -5285,18 +5293,22 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
int rtype, quoted, flags;
{
int vtype, xc;
- char *temp1, *val;
+ char *temp1, *val, *oname;
SHELL_VAR *v;
xc = xform[0];
if (value == 0 && xc != 'A' && xc != 'a')
return ((char *)NULL);
+ oname = this_command_name;
this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1)
- return ((char *)NULL);
+ {
+ this_command_name = oname;
+ return ((char *)NULL);
+ }
/* check for valid values of xc */
switch (xc)
@@ -5308,6 +5320,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
case 'Q': /* quote reusably */
break;
default:
+ this_command_name = oname;
return &expand_param_error;
}
@@ -5350,6 +5363,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
break;
}
+ this_command_name = oname;
return temp1;
}
@@ -7631,17 +7645,21 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
int quoted, pflags, flags;
{
int vtype, mflags, starsub, delim;
- char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
+ char *val, *temp, *pat, *rep, *p, *lpatsub, *tt, *oname;
SHELL_VAR *v;
if (value == 0)
return ((char *)NULL);
- this_command_name = varname;
+ oname = this_command_name;
+ this_command_name = varname; /* error messages */
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1)
- return ((char *)NULL);
+ {
+ this_command_name = oname;
+ return ((char *)NULL);
+ }
starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB;
@@ -7769,6 +7787,8 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
FREE (rep);
free (lpatsub);
+ this_command_name = oname;
+
return temp;
}
@@ -7825,17 +7845,21 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
int quoted, flags;
{
int vtype, starsub, modop, mflags, x;
- char *val, *temp, *pat, *p, *lpat, *tt;
+ char *val, *temp, *pat, *p, *lpat, *tt, *oname;
SHELL_VAR *v;
if (value == 0)
return ((char *)NULL);
+ oname = this_command_name;
this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1)
- return ((char *)NULL);
+ {
+ this_command_name = oname;
+ return ((char *)NULL);
+ }
starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB;
@@ -7912,6 +7936,8 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
FREE (pat);
free (lpat);
+ this_command_name = oname;
+
return temp;
}
@@ -9779,7 +9805,9 @@ finished_with_string:
{
istring[0] = CTLNUL;
istring[1] = '\0';
- tword = make_bare_word (istring);
+ tword = alloc_word_desc ();
+ tword->word = istring;
+ istring = 0; /* avoid later free() */
tword->flags |= W_HASQUOTEDNULL; /* XXX */
list = make_word_list (tword, (WORD_LIST *)NULL);
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
@@ -9792,22 +9820,16 @@ finished_with_string:
null arguments */
else if (quoted_state == UNQUOTED || quoted_dollar_at)
list = (WORD_LIST *)NULL;
-#if 0
- else
- {
- tword = make_bare_word (istring);
- if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
- tword->flags |= W_QUOTED;
- list = make_word_list (tword, (WORD_LIST *)NULL);
- }
-#else
else
list = (WORD_LIST *)NULL;
-#endif
}
else if (word->flags & W_NOSPLIT)
{
- tword = make_bare_word (istring);
+ tword = alloc_word_desc ();
+ tword->word = istring;
+ if (had_quoted_null && QUOTED_NULL (istring))
+ tword->flags |= W_HASQUOTEDNULL;
+ istring = 0; /* avoid later free() */
if (word->flags & W_ASSIGNMENT)
tword->flags |= W_ASSIGNMENT; /* XXX */
if (word->flags & W_COMPASSIGN)
@@ -9820,8 +9842,6 @@ finished_with_string:
tword->flags |= W_NOEXPAND; /* XXX */
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
tword->flags |= W_QUOTED;
- if (had_quoted_null && QUOTED_NULL (istring))
- tword->flags |= W_HASQUOTEDNULL;
list = make_word_list (tword, (WORD_LIST *)NULL);
}
else
@@ -9855,47 +9875,36 @@ finished_with_string:
double-quoted $@ while expanding it. */
else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
{
+ tword = alloc_word_desc ();
/* Only split and rejoin if we have to */
if (*ifs_chars && *ifs_chars != ' ')
{
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
- tstring = string_list (list);
+ tword->word = string_list (list);
}
else
- tstring = istring;
- tword = make_bare_word (tstring);
- if (tstring != istring)
- free (tstring);
- goto set_word_flags;
- }
- /* This is the attempt to make $* in an assignment context (a=$*) and
- array variables subscripted with * in an assignment context (a=${foo[*]})
- behave similarly. It has side effects that, though they increase
- compatibility with other shells, are not backwards compatible. */
-#if 0
- else if (has_dollar_at && quoted == 0 && ifs_chars && (word->flags & W_ASSIGNRHS))
- {
- tword = make_bare_word (istring);
+ tword->word = istring;
+ if (had_quoted_null && QUOTED_NULL (istring))
+ tword->flags |= W_HASQUOTEDNULL; /* XXX */
+ if (tword->word != istring)
+ free (istring);
+ istring = 0; /* avoid later free() */
goto set_word_flags;
}
-#endif
else if (has_dollar_at && ifs_chars)
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
else
{
-#if 0
- /* XXX might want to use *expanded_something == 0 instead of
- local_expanded here */
- if (local_expanded == 0 && has_quoted_ifs)
-#else
+ tword = alloc_word_desc ();
if (expanded_something && *expanded_something == 0 && has_quoted_ifs)
-#endif
- {
- tword = alloc_word_desc ();
- tword->word = remove_quoted_ifs (istring);
- }
+ tword->word = remove_quoted_ifs (istring);
else
- tword = make_bare_word (istring);
+ tword->word = istring;
+ if (had_quoted_null && QUOTED_NULL (istring))
+ tword->flags |= W_HASQUOTEDNULL; /* XXX */
+ if (tword->word != istring)
+ free (istring);
+ istring = 0; /* avoid later free() */
set_word_flags:
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
tword->flags |= W_QUOTED;
@@ -9909,8 +9918,6 @@ set_word_flags:
tword->flags |= W_NOBRACE;
if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND;
- if (had_quoted_null && QUOTED_NULL (istring))
- tword->flags |= W_HASQUOTEDNULL; /* XXX */
list = make_word_list (tword, (WORD_LIST *)NULL);
}
}
diff --git a/test.c b/test.c
index cf762df..8589485 100644
--- a/test.c
+++ b/test.c
@@ -627,8 +627,12 @@ unary_test (op, arg)
if (v == 0 && valid_array_reference (arg, 0))
{
char *t;
- t = array_value (arg, 0, 0, (int *)0, (arrayind_t *)0);
- return (t ? TRUE : FALSE);
+ int rtype, ret;
+ t = array_value (arg, 0, 0, &rtype, (arrayind_t *)0);
+ ret = t ? TRUE : FALSE;
+ if (rtype > 0) /* subscript is * or @ */
+ free (t);
+ return ret;
}
else if (v && invisible_p (v) == 0 && array_p (v))
{
diff --git a/trap.c b/trap.c
index 49feb5b..5d9f559 100644
--- a/trap.c
+++ b/trap.c
@@ -494,6 +494,8 @@ first_pending_trap ()
return -1;
}
+/* Return > 0 if any of the "real" signals (not fake signals like EXIT) are
+ trapped. */
int
any_signals_trapped ()
{