From 1975c9b5fa725ef8bdec6ee32d56e63fdf2923af Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Thu, 1 Dec 2016 16:58:13 -0500 Subject: [PATCH] commit bash-20161122 snapshot --- CWRU/CWRU.chlog | 104 ++++++++++++++++++++++++++++++++++++++++++++ bashhist.c | 4 +- bashhist.h | 6 +++ builtins/read.def | 3 +- doc/bash.1 | 3 +- doc/bashref.texi | 3 +- execute_cmd.c | 3 ++ flags.c | 10 ++--- flags.h | 1 + lib/glob/strmatch.h | 2 + parse.y | 24 +++++++++- shell.c | 1 + subst.c | 86 ++++++++++++++++++++++++------------ test.c | 4 +- tests/RUN-ONE-TEST | 2 +- 15 files changed, 212 insertions(+), 44 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index f3ff3e7d..3c8373eb 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 <\> and + skip to the end of string processing. Fixes oob-read error + reported by Jerzy Kramarz + +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 + + - ANDOR: check s[1] before checking s[2] in case s[1] == end of string. + Fixes oob-read error reported by Jerzy Kramarz + +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 + + +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 + + 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 + + 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 + + 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 + +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 diff --git a/bashhist.c b/bashhist.c index 829952b4..c0d6f64c 100644 --- a/bashhist.c +++ b/bashhist.c @@ -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; diff --git a/bashhist.h b/bashhist.h index c44e7c60..34bc2347 100644 --- a/bashhist.h +++ b/bashhist.h @@ -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' */ diff --git a/builtins/read.def b/builtins/read.def index a7f80b3f..8d1fd452 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -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; diff --git a/doc/bash.1 b/doc/bash.1 index 9e043cd5..00d47896 100644 --- a/doc/bash.1 +++ b/doc/bash.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 diff --git a/doc/bashref.texi b/doc/bashref.texi index 7072cdff..b2dff8c0 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -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 diff --git a/execute_cmd.c b/execute_cmd.c index d85f3904..f6ce256e 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -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 diff --git a/flags.c b/flags.c index 4b94fb03..3177efe4 100644 --- a/flags.c +++ b/flags.c @@ -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; diff --git a/flags.h b/flags.h index d5ed334e..07149eab 100644 --- a/flags.h +++ b/flags.h @@ -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) diff --git a/lib/glob/strmatch.h b/lib/glob/strmatch.h index 5c99e0ca..aee00cc8 100644 --- a/lib/glob/strmatch.h +++ b/lib/glob/strmatch.h @@ -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 diff --git a/parse.y b/parse.y index 5742a63a..7543dc03 100644 --- a/parse.y +++ b/parse.y @@ -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] != ')') diff --git a/shell.c b/shell.c index 45b77f9e..fb75ea09 100644 --- a/shell.c +++ b/shell.c @@ -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 } diff --git a/subst.c b/subst.c index 5664ba1c..cca86890 100644 --- a/subst.c +++ b/subst.c @@ -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); diff --git a/test.c b/test.c index 8589485a..d27a463c 100644 --- a/test.c +++ b/test.c @@ -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. */ diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index a5ab273d..d29259a9 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -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