mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-26 07:13:10 +02:00
commit bash-20161122 snapshot
This commit is contained in:
+104
@@ -12458,3 +12458,107 @@ builtins/shopt.def
|
||||
builtins/common.c
|
||||
- display_signal_list: make `kill -l 0' print `EXIT', modifying change
|
||||
from 9/17
|
||||
|
||||
11/21
|
||||
-----
|
||||
subst.c
|
||||
- expand_word_internal: when the shell encounters a backslash as the
|
||||
last character of the string, don't try to add a '\'0' to the end
|
||||
of the string if the string is quoted, just add a <CTLESC><\> and
|
||||
skip to the end of string processing. Fixes oob-read error
|
||||
reported by Jerzy Kramarz <op7ica@gmail.com>
|
||||
|
||||
test.c
|
||||
- two_arguments: check argv[pos][1] before checking argv[pos][2] when
|
||||
looking for a unary argument. Fixes oob-read error on single `-'
|
||||
in unary operator position reported by Jerzy Kramarz
|
||||
<op7ica@gmail.com>
|
||||
- ANDOR: check s[1] before checking s[2] in case s[1] == end of string.
|
||||
Fixes oob-read error reported by Jerzy Kramarz <op7ica@gmail.com>
|
||||
|
||||
subst.c
|
||||
- command_substitute: now takes additional flags argument, changed one
|
||||
caller (param_expand) to pass through PF_ASSIGNRHS flag; other callers
|
||||
pass 0
|
||||
- command_substitute: pass through flags argument to read_comsub
|
||||
- read_comsub: now takes additional new flags argument to indicate
|
||||
whether or not the word is in a context where word splitting will
|
||||
eventually be performed
|
||||
- read_comsub: if we are running in a context where word splitting
|
||||
will not take place (PF_ASSIGNRHS), we read a CTLESC, and CTLESC is
|
||||
in $IFS, add a CTLESC to make sure it gets through a round of
|
||||
dequoting
|
||||
|
||||
11/23
|
||||
-----
|
||||
parse.y
|
||||
- xparse_dolparen: since reset_parser frees the pushed string list,
|
||||
and this is supposed to be a separate parsing context, we need to
|
||||
save and restore pushed_string_list around the call to parse_string
|
||||
and reset_parser. Fixes bug reported by Dan Douglas
|
||||
<ormaaj@gmail.com>
|
||||
|
||||
bashhist.h
|
||||
- HISTEXPAND_DEFAULT: default value of history_expansion, moved here
|
||||
from flags.c
|
||||
|
||||
flags.[ch]
|
||||
- histexp_flag: new variable, this is what set -H/set -o histexpand
|
||||
sets; history_expansion set to value of this variable; defaults to 0
|
||||
- history_expansion: now set to HISTEXPAND_DEFAULT
|
||||
|
||||
bashhist.c
|
||||
- bash_history_reinit: if interact == 0, set history_expansion to the
|
||||
value of histexp_flag, to allow -H option to enable history
|
||||
expansion
|
||||
- bash_history_reinit: if interact == 0, make sure
|
||||
history_expansion_inhibited is set opposite of histexp_flag, so
|
||||
enabling history expansion with -H invocation option turns off
|
||||
inhibited expansion. If interactive shell, we turn it off so
|
||||
history_expansion controls whether or not history expansion takes
|
||||
place. In practice, this function is always called with interact == 0,
|
||||
and -c command still doesn't perform history expansion
|
||||
|
||||
shell.c
|
||||
- init_interactive: make sure histexp_flag and history_expansion are
|
||||
identical in an interactive shell; allows both -H/+H option and
|
||||
default compilation options (HISTEXPAND_DEFAULT) to work
|
||||
|
||||
11/24
|
||||
-----
|
||||
subst.c
|
||||
- get_word_from_string: take advantage of the fact that SEPARATORS is
|
||||
always a (possibly local) copy of IFS, so build a local charmap of
|
||||
separators and use it instead of the (cached and possibly stale)
|
||||
ifs_cmap map and isifs macro. Fixes bug with -N stripping leading
|
||||
whitespace reported by Clark Wang <clarkw@vmware.com>
|
||||
|
||||
11/25
|
||||
-----
|
||||
builtins/read.def
|
||||
- read_builtin: make `i' volatile, since auto variables are technically
|
||||
undefined after a longjmp, and a timeout on SIGALRM causes one.
|
||||
Fix suggested by Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
11/27
|
||||
-----
|
||||
parse.y
|
||||
- shell_getc: if we are reading input from a string, and we get the
|
||||
ending '\0', and we are not expanding an alias, return EOF right
|
||||
away. It might be an eval'ed string that has a syntax error.
|
||||
Fixes bug reported by Dan Douglas <ormaaj@gmail.com>
|
||||
|
||||
11/28
|
||||
-----
|
||||
subst.c
|
||||
- expand_word_internal: if we're expanding a quoted string containing
|
||||
a tilde as the first character of a word, only expand the tilde if
|
||||
we're expanding an array subscript (Q_ARRAYSUB), not if we're
|
||||
expanding any arithmetic expression (Q_ARITH). This fixes a
|
||||
backwards compatibility issue with expressions like ~0 reported by
|
||||
Bize Ma <binaryzebra@gmail.com>
|
||||
|
||||
subst.c
|
||||
- parameter_brace_expand_indir: if the variable is not special and
|
||||
the indirect variable is unset (!variable where variable is unset),
|
||||
report an error. Fixes omission reported by otenba@protonmail.com
|
||||
|
||||
+2
-2
@@ -272,8 +272,8 @@ bash_history_reinit (interact)
|
||||
int interact;
|
||||
{
|
||||
#if defined (BANG_HISTORY)
|
||||
history_expansion = interact != 0;
|
||||
history_expansion_inhibited = 1; /* XXX */
|
||||
history_expansion = (interact == 0) ? histexp_flag : HISTEXPAND_DEFAULT;
|
||||
history_expansion_inhibited = (interact == 0) ? 1 - histexp_flag : 0; /* changed in bash_history_enable() */
|
||||
history_inhibit_expansion_function = bash_history_inhibit_expansion;
|
||||
#endif
|
||||
remember_on_history = enable_history_list;
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
|
||||
#define HC_IGNBOTH (HC_IGNSPACE|HC_IGNDUPS)
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
# define HISTEXPAND_DEFAULT 0
|
||||
#else
|
||||
# define HISTEXPAND_DEFAULT 1
|
||||
#endif
|
||||
|
||||
extern int remember_on_history;
|
||||
extern int enable_history_list; /* value for `set -o history' */
|
||||
extern int literal_history; /* controlled by `shopt lithist' */
|
||||
|
||||
+2
-1
@@ -178,7 +178,8 @@ read_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
register char *varname;
|
||||
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
||||
int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
||||
volatile int i;
|
||||
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;
|
||||
|
||||
+2
-1
@@ -2794,7 +2794,8 @@ Any incorrectly formed brace expansion is left unchanged.
|
||||
A \fB{\fP or \fB,\fP may be quoted with a backslash to prevent its
|
||||
being considered part of a brace expression.
|
||||
To avoid conflicts with parameter expansion, the string \fB${\fP
|
||||
is not considered eligible for brace expansion.
|
||||
is not considered eligible for brace expansion, and inhibits brace
|
||||
expansion until the closing \fB}\fP.
|
||||
.PP
|
||||
This construct is typically used as shorthand when the common
|
||||
prefix of the strings to be generated is longer than in the
|
||||
|
||||
+2
-1
@@ -1766,7 +1766,8 @@ in the result. It is strictly textual. Bash
|
||||
does not apply any syntactic interpretation to the context of the
|
||||
expansion or the text between the braces.
|
||||
To avoid conflicts with parameter expansion, the string @samp{$@{}
|
||||
is not considered eligible for brace expansion.
|
||||
is not considered eligible for brace expansion,
|
||||
and inhibits brace expansion until the closing @samp{@}}..
|
||||
|
||||
A correctly-formed brace expansion must contain unquoted opening
|
||||
and closing braces, and at least one unquoted comma or a valid
|
||||
|
||||
@@ -4381,7 +4381,10 @@ run_builtin:
|
||||
}
|
||||
result = builtin_status (result);
|
||||
if (builtin_is_special)
|
||||
{
|
||||
itrace("special builtin failed with flags = %d", simple_command->flags);
|
||||
special_builtin_failed = 1;
|
||||
}
|
||||
}
|
||||
/* In POSIX mode, if there are assignment statements preceding
|
||||
a special builtin, they persist after the builtin
|
||||
|
||||
@@ -130,11 +130,8 @@ int hashing_enabled = 1;
|
||||
#if defined (BANG_HISTORY)
|
||||
/* Non-zero means that we are doing history expansion. The default.
|
||||
This means !22 gets the 22nd line of history. */
|
||||
# if defined (STRICT_POSIX)
|
||||
int history_expansion = 0;
|
||||
# else
|
||||
int history_expansion = 1;
|
||||
# endif
|
||||
int history_expansion = HISTEXPAND_DEFAULT;
|
||||
int histexp_flag = 0;
|
||||
#endif /* BANG_HISTORY */
|
||||
|
||||
/* Non-zero means that we allow comments to appear in interactive commands. */
|
||||
@@ -211,7 +208,7 @@ const struct flags_alist shell_flags[] = {
|
||||
{ 'C', &noclobber },
|
||||
{ 'E', &error_trace_mode },
|
||||
#if defined (BANG_HISTORY)
|
||||
{ 'H', &history_expansion },
|
||||
{ 'H', &histexp_flag },
|
||||
#endif /* BANG_HISTORY */
|
||||
{ 'I', &no_invisible_vars },
|
||||
{ 'P', &no_symbolic_links },
|
||||
@@ -265,6 +262,7 @@ change_flag (flag, on_or_off)
|
||||
{
|
||||
#if defined (BANG_HISTORY)
|
||||
case 'H':
|
||||
history_expansion = histexp_flag;
|
||||
if (on_or_off == FLAG_ON)
|
||||
bash_initialize_history ();
|
||||
break;
|
||||
|
||||
@@ -60,6 +60,7 @@ extern int brace_expansion;
|
||||
|
||||
#if defined (BANG_HISTORY)
|
||||
extern int history_expansion;
|
||||
extern int histexp_flag;
|
||||
#endif /* BANG_HISTORY */
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
|
||||
|
||||
#define FNM_FIRSTCHAR (1 << 6) /* Match only the first character */
|
||||
|
||||
/* Value returned by `strmatch' if STRING does not match PATTERN. */
|
||||
#undef FNM_NOMATCH
|
||||
|
||||
|
||||
@@ -2311,6 +2311,14 @@ shell_getc (remove_quoted_newline)
|
||||
#if 0
|
||||
internal_warning ("shell_getc: ignored null byte in input");
|
||||
#endif
|
||||
if (bash_input.type == st_string)
|
||||
{
|
||||
if (i == 0)
|
||||
shell_input_line_terminator = EOF;
|
||||
shell_input_line[i] = '\0';
|
||||
c = EOF;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3131,6 +3139,15 @@ read_token (command)
|
||||
return (yacc_EOF);
|
||||
}
|
||||
|
||||
/* If we hit the end of the string and we're not expanding an alias (e.g.,
|
||||
we are eval'ing a string that is an incomplete command), return EOF */
|
||||
if (character == '\0' && bash_input.type == st_string && expanding_alias() == 0)
|
||||
{
|
||||
itrace("shell_getc: bash_input.location.string = `%s'", bash_input.location.string);
|
||||
EOF_Reached = 1;
|
||||
return (yacc_EOF);
|
||||
}
|
||||
|
||||
if MBTEST(character == '#' && (!interactive || interactive_comments))
|
||||
{
|
||||
/* A comment. Discard until EOL or EOF, and then return a newline. */
|
||||
@@ -4226,6 +4243,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||
sh_input_line_state_t ls;
|
||||
int orig_ind, nc, sflags, orig_eof_token;
|
||||
char *ret, *s, *ep, *ostring;
|
||||
STRING_SAVER *saved_pushed_strings;
|
||||
|
||||
/*yydebug = 1;*/
|
||||
orig_ind = *indp;
|
||||
@@ -4238,6 +4256,8 @@ xparse_dolparen (base, string, indp, flags)
|
||||
save_parser_state (&ps);
|
||||
save_input_line_state (&ls);
|
||||
orig_eof_token = shell_eof_token;
|
||||
saved_pushed_strings = pushed_string_list; /* separate parsing context */
|
||||
pushed_string_list = (STRING_SAVER *)NULL;
|
||||
|
||||
/*(*/
|
||||
parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
|
||||
@@ -4251,6 +4271,8 @@ xparse_dolparen (base, string, indp, flags)
|
||||
/* reset_parser clears shell_input_line and associated variables */
|
||||
restore_input_line_state (&ls);
|
||||
|
||||
pushed_string_list = saved_pushed_strings;
|
||||
|
||||
token_to_read = 0;
|
||||
|
||||
/* If parse_string returns < 0, we need to jump to top level with the
|
||||
@@ -4260,7 +4282,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||
|
||||
/* Need to find how many characters parse_and_execute consumed, update
|
||||
*indp, if flags != 0, copy the portion of the string parsed into RET
|
||||
and return it. If flags & 1 (EX_NOALLOC) we can return NULL. */
|
||||
and return it. If flags & 1 (SX_NOALLOC) we can return NULL. */
|
||||
|
||||
/*(*/
|
||||
if (ep[-1] != ')')
|
||||
|
||||
@@ -1722,6 +1722,7 @@ init_interactive ()
|
||||
interactive = 1;
|
||||
#if defined (HISTORY)
|
||||
remember_on_history = enable_history_list = 1; /* XXX */
|
||||
histexp_flag = history_expansion; /* XXX */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ static char *parameter_brace_transform __P((char *, char *, int, char *, int, in
|
||||
|
||||
static char *process_substitute __P((char *, int));
|
||||
|
||||
static char *read_comsub __P((int, int, int *));
|
||||
static char *read_comsub __P((int, int, int, int *));
|
||||
|
||||
#ifdef ARRAY_VARS
|
||||
static arrayind_t array_length_reference __P((char *));
|
||||
@@ -2851,11 +2851,15 @@ list_string (string, separators, quoted)
|
||||
|
||||
/* Parse a single word from STRING, using SEPARATORS to separate fields.
|
||||
ENDPTR is set to the first character after the word. This is used by
|
||||
the `read' builtin. This is never called with SEPARATORS != $IFS;
|
||||
it should be simplified.
|
||||
the `read' builtin.
|
||||
|
||||
This is never called with SEPARATORS != $IFS, and takes advantage of that.
|
||||
|
||||
XXX - this function is very similar to list_string; they should be
|
||||
combined - XXX */
|
||||
|
||||
#define islocalsep(c) (local_cmap[(unsigned char)(c)] != 0)
|
||||
|
||||
char *
|
||||
get_word_from_string (stringp, separators, endptr)
|
||||
char **stringp, *separators, **endptr;
|
||||
@@ -2863,6 +2867,7 @@ get_word_from_string (stringp, separators, endptr)
|
||||
register char *s;
|
||||
char *current_word;
|
||||
int sindex, sh_style_split, whitesep, xflags;
|
||||
unsigned char local_cmap[UCHAR_MAX+1]; /* really only need single-byte chars here */
|
||||
size_t slen;
|
||||
|
||||
if (!stringp || !*stringp || !**stringp)
|
||||
@@ -2872,20 +2877,23 @@ get_word_from_string (stringp, separators, endptr)
|
||||
separators[1] == '\t' &&
|
||||
separators[2] == '\n' &&
|
||||
separators[3] == '\0';
|
||||
for (xflags = 0, s = ifs_value; s && *s; s++)
|
||||
memset (local_cmap, '\0', sizeof (local_cmap));
|
||||
for (xflags = 0, s = separators; s && *s; s++)
|
||||
{
|
||||
if (*s == CTLESC) xflags |= SX_NOCTLESC;
|
||||
if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
|
||||
local_cmap[(unsigned char)*s] = 1; /* local charmap of separators */
|
||||
}
|
||||
|
||||
s = *stringp;
|
||||
slen = 0;
|
||||
|
||||
/* Remove sequences of whitespace at the beginning of STRING, as
|
||||
long as those characters appear in IFS. */
|
||||
if (sh_style_split || !separators || !*separators)
|
||||
long as those characters appear in SEPARATORS. This happens if
|
||||
SEPARATORS == $' \t\n' or if IFS is unset. */
|
||||
if (sh_style_split || separators == 0)
|
||||
{
|
||||
for (; *s && spctabnl (*s) && isifs (*s); s++);
|
||||
for (; *s && spctabnl (*s) && islocalsep (*s); s++);
|
||||
|
||||
/* If the string is nothing but whitespace, update it and return. */
|
||||
if (!*s)
|
||||
@@ -2925,19 +2933,19 @@ get_word_from_string (stringp, separators, endptr)
|
||||
|
||||
/* Now skip sequences of space, tab, or newline characters if they are
|
||||
in the list of separators. */
|
||||
while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
|
||||
while (s[sindex] && spctabnl (s[sindex]) && islocalsep (s[sindex]))
|
||||
sindex++;
|
||||
|
||||
/* If the first separator was IFS whitespace and the current character is
|
||||
a non-whitespace IFS character, it should be part of the current field
|
||||
delimiter, not a separate delimiter that would result in an empty field.
|
||||
Look at POSIX.2, 3.6.5, (3)(b). */
|
||||
if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
|
||||
if (s[sindex] && whitesep && islocalsep (s[sindex]) && !spctabnl (s[sindex]))
|
||||
{
|
||||
sindex++;
|
||||
/* An IFS character that is not IFS white space, along with any adjacent
|
||||
IFS white space, shall delimit a field. */
|
||||
while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
|
||||
while (s[sindex] && spctabnl (s[sindex]) && islocalsep(s[sindex]))
|
||||
sindex++;
|
||||
}
|
||||
|
||||
@@ -3716,10 +3724,12 @@ expand_string_assignment (string, quoted)
|
||||
expand_no_split_dollar_star = 1;
|
||||
|
||||
#if 0
|
||||
/* Other shells (ksh93) do it this way, affects how $@ is expanded in
|
||||
constructs like bar=${@#0} (preserves the spaces resulting from the
|
||||
expansion of $@ in a context where you don't do word splitting) */
|
||||
td.flags = W_ASSIGNRHS|W_NOSPLIT2;
|
||||
/* Other shells (ksh93) do it this way, which affects how $@ is expanded
|
||||
in constructs like bar=${@#0} (preserves the spaces resulting from the
|
||||
expansion of $@ in a context where you don't do word splitting); Posix
|
||||
interp 888 makes the expansion of $@ in contexts where word splitting
|
||||
is not performed unspecified. */
|
||||
td.flags = W_ASSIGNRHS|W_NOSPLIT2; /* Posix interp 888 */
|
||||
#else
|
||||
td.flags = W_ASSIGNRHS;
|
||||
#endif
|
||||
@@ -4542,7 +4552,7 @@ match_upattern (string, pat, mtype, sp, ep)
|
||||
|
||||
p = npat = (char *)xmalloc (len + 3);
|
||||
p1 = pat;
|
||||
if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
|
||||
if ((mtype != MATCH_BEG) && (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob)))
|
||||
*p++ = '*';
|
||||
while (*p1)
|
||||
*p++ = *p1++;
|
||||
@@ -4553,7 +4563,7 @@ match_upattern (string, pat, mtype, sp, ep)
|
||||
/* If the pattern ends with a `*' we leave it alone if it's preceded by
|
||||
an even number of backslashes, but if it's escaped by a backslash
|
||||
we need to add another `*'. */
|
||||
if (p1[-1] == '*' && (unescaped_backslash = p1[-2] == '\\'))
|
||||
if ((mtype != MATCH_END) && (p1[-1] == '*' && (unescaped_backslash = p1[-2] == '\\')))
|
||||
{
|
||||
pp = p1 - 3;
|
||||
while (pp >= pat && *pp-- == '\\')
|
||||
@@ -4561,7 +4571,7 @@ match_upattern (string, pat, mtype, sp, ep)
|
||||
if (unescaped_backslash)
|
||||
*p++ = '*';
|
||||
}
|
||||
else if (p1[-1] != '*')
|
||||
else if (mtype != MATCH_END && p1[-1] != '*')
|
||||
*p++ = '*';
|
||||
#else
|
||||
if (p1[-1] != '*' || p1[-2] == '\\')
|
||||
@@ -5999,8 +6009,8 @@ process_substitute (string, open_for_read_in_child)
|
||||
/***********************************/
|
||||
|
||||
static char *
|
||||
read_comsub (fd, quoted, rflag)
|
||||
int fd, quoted;
|
||||
read_comsub (fd, quoted, flags, rflag)
|
||||
int fd, quoted, flags;
|
||||
int *rflag;
|
||||
{
|
||||
char *istring, buf[128], *bufp, *s;
|
||||
@@ -6011,13 +6021,8 @@ read_comsub (fd, quoted, rflag)
|
||||
istring = (char *)NULL;
|
||||
istring_index = istring_size = bufn = tflag = 0;
|
||||
|
||||
#if 0
|
||||
for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
|
||||
skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
|
||||
#else
|
||||
skip_ctlesc = ifs_cmap[CTLESC];
|
||||
skip_ctlnul = ifs_cmap[CTLNUL];
|
||||
#endif
|
||||
|
||||
nullbyte = 0;
|
||||
|
||||
@@ -6054,6 +6059,8 @@ read_comsub (fd, quoted, rflag)
|
||||
/* This is essentially quote_string inline */
|
||||
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
|
||||
istring[istring_index++] = CTLESC;
|
||||
else if ((flags & PF_ASSIGNRHS) && skip_ctlesc && c == CTLESC)
|
||||
istring[istring_index++] = CTLESC;
|
||||
/* Escape CTLESC and CTLNUL in the output to protect those characters
|
||||
from the rest of the word expansions (word splitting and globbing.)
|
||||
This is essentially quote_escapes inline. */
|
||||
@@ -6340,7 +6347,7 @@ command_substitute (string, quoted, flags)
|
||||
close (fildes[1]);
|
||||
|
||||
tflag = 0;
|
||||
istring = read_comsub (fildes[0], quoted, &tflag);
|
||||
istring = read_comsub (fildes[0], quoted, flags, &tflag);
|
||||
|
||||
close (fildes[0]);
|
||||
|
||||
@@ -6745,6 +6752,15 @@ parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, c
|
||||
}
|
||||
}
|
||||
|
||||
if (var_is_special == 0 && v == 0)
|
||||
{
|
||||
report_error (_("%s: invalid indirect expansion"), name);
|
||||
w = alloc_word_desc ();
|
||||
w->word = &expand_param_error;
|
||||
w->flags = 0;
|
||||
return (w);
|
||||
}
|
||||
|
||||
t = parameter_brace_find_indir (name, var_is_special, quoted, 0);
|
||||
|
||||
chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
|
||||
@@ -6753,7 +6769,7 @@ parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, c
|
||||
|
||||
if (valid_brace_expansion_word (t, SPECIAL_VAR (t, 0)) == 0)
|
||||
{
|
||||
report_error (_("%s: bad substitution"), t);
|
||||
report_error (_("%s: invalid variable name"), t);
|
||||
free (t);
|
||||
w = alloc_word_desc ();
|
||||
w->word = &expand_param_error;
|
||||
@@ -9202,7 +9218,7 @@ expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_somethin
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
|
||||
/* Don't need the string length for the SADD... and COPY_ macros unless
|
||||
multibyte characters are possible. */
|
||||
multibyte characters are possible, but do need it for bounds checking. */
|
||||
string_size = (mb_cur_max > 1) ? strlen (string) : 1;
|
||||
|
||||
if (contains_dollar_at)
|
||||
@@ -9351,10 +9367,13 @@ add_string:
|
||||
at the start of a word or after an unquoted : or = in an
|
||||
assignment statement, we don't do tilde expansion. If we don't want
|
||||
tilde expansion when expanding words to be passed to the arithmetic
|
||||
evaluator, remove the check for Q_ARITH. */
|
||||
evaluator, remove the check for Q_ARITH. Right now, the code
|
||||
suppresses tilde expansion when expanding in a pure arithmetic
|
||||
context, but allows it when expanding an array subscript. This is
|
||||
for backwards compatibility, but I figure nobody's relying on it */
|
||||
if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
|
||||
(sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
|
||||
((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARITH) == 0)))
|
||||
((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARRAYSUB) == 0)))
|
||||
{
|
||||
word->flags &= ~W_ITILDE;
|
||||
if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
|
||||
@@ -9515,6 +9534,15 @@ add_string:
|
||||
|
||||
SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
|
||||
}
|
||||
else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && c == 0)
|
||||
{
|
||||
RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
|
||||
DEFAULT_ARRAY_SIZE);
|
||||
istring[istring_index++] = CTLESC;
|
||||
istring[istring_index++] = '\\';
|
||||
istring[istring_index] = '\0';
|
||||
break;
|
||||
}
|
||||
else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
|
||||
{
|
||||
SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
|
||||
|
||||
@@ -740,7 +740,7 @@ two_arguments ()
|
||||
{
|
||||
if (argv[pos][0] == '!' && argv[pos][1] == '\0')
|
||||
return (argv[pos + 1][0] == '\0');
|
||||
else if (argv[pos][0] == '-' && argv[pos][2] == '\0')
|
||||
else if (argv[pos][0] == '-' && argv[pos][1] && argv[pos][2] == '\0')
|
||||
{
|
||||
if (test_unop (argv[pos]))
|
||||
return (unary_operator ());
|
||||
@@ -753,7 +753,7 @@ two_arguments ()
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define ANDOR(s) (s[0] == '-' && !s[2] && (s[1] == 'a' || s[1] == 'o'))
|
||||
#define ANDOR(s) (s[0] == '-' && (s[1] == 'a' || s[1] == 'o') && s[2] == 0)
|
||||
|
||||
/* This could be augmented to handle `-t' as equivalent to `-t 1', but
|
||||
POSIX requires that `-t' be given an argument. */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
Reference in New Issue
Block a user