diff options
| author | Chet Ramey <chet.ramey@case.edu> | 2016-11-10 11:32:12 -0500 |
|---|---|---|
| committer | Chet Ramey <chet.ramey@case.edu> | 2016-11-10 11:32:12 -0500 |
| commit | 78a3f8a4bae8ef98daa26b64ddbc03c6fc3ffcd0 (patch) | |
| tree | 18a0ee4f8546d38f23f334afc65956fd3a108c07 | |
| parent | ec1101c37ea25a61db37c268f736089061c9afaa (diff) | |
| download | bash-78a3f8a4bae8ef98daa26b64ddbc03c6fc3ffcd0.tar.gz | |
commit bash-20161108 snapshot
| -rw-r--r-- | CWRU/CWRU.chlog | 91 | ||||
| -rw-r--r-- | builtins/common.c | 4 | ||||
| -rw-r--r-- | builtins/evalstring.c | 5 | ||||
| -rw-r--r-- | builtins/read.def | 8 | ||||
| -rw-r--r-- | builtins/trap.def | 4 | ||||
| -rw-r--r-- | eval.c | 2 | ||||
| -rw-r--r-- | execute_cmd.c | 29 | ||||
| -rw-r--r-- | expr.c | 15 | ||||
| -rw-r--r-- | lib/sh/unicode.c | 6 | ||||
| -rw-r--r-- | nojobs.c | 10 | ||||
| -rw-r--r-- | subst.c | 123 | ||||
| -rw-r--r-- | test.c | 8 | ||||
| -rw-r--r-- | trap.c | 2 |
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; @@ -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. */ @@ -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); @@ -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; } @@ -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); } } @@ -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)) { @@ -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 () { |
