From 0e8fd324906fe1b9ad969fbac5dbe9fadf57a769 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Mon, 14 Jan 2019 10:44:20 -0500 Subject: [PATCH] commit bash-20190111 snapshot --- CWRU/CWRU.chlog | 35 +++++++++++++++++++++++++++++++++++ builtins/hash.def | 4 ++-- lib/glob/glob.c | 14 ++++++++++++-- parse.y | 5 ++++- parser.h | 3 ++- tests/alias.right | 1 + tests/alias4.sub | 7 +++++++ variables.c | 1 - 8 files changed, 63 insertions(+), 7 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 30124c559..e972bf4ed 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -5026,3 +5026,38 @@ test.c arrayfunc.c - array_expand_index: call evalexp with EXP_EXPANDED flag, since we have run the string through expand_arith_string already + + 1/11 + ---- +parser.h + - PST_ENDALIAS: new state, means we just consumed the last character + of an alias expansion and returned the fake space + +parse.y + - shell_getc: add PST_ENDALIAS to parser_state before returning the + fake space that marks the end of the alias, making sure to do it + only once. With that set, fall through to the pop_string(), making + sure to unset PST_ENDALIAS. Fixes alias bug reported by + Ante Peric + + 1/12 + ---- +lib/glob/glob.c + - {extglob,wextglob}_skipname: make sure we check the rest of the + pattern if the extglob pattern is null, and therefore won't match + anything. If that is followed by a `.', quoted or unquoted, we can + match a leading `.' in the pathname. This code is currently not + active. + +builtins/hash.def + - hash_builtin: if -d is supplied without an argument, print an error + message and return failure, just like -t without an argument. Fixes + inconsistency reported by Dan Jacobson + + 1/13 + ---- +parse.y + - shell_getc: use shellblank when testing the last character of an + alias to determine whether or not to add a trailing space instead + of testing against a space only. These are the non-shell-metacharacters + that can delimit words. Used together with PST_ENDALIAS diff --git a/builtins/hash.def b/builtins/hash.def index b30393081..4de3a910d 100644 --- a/builtins/hash.def +++ b/builtins/hash.def @@ -123,9 +123,9 @@ hash_builtin (list) list = loptend; /* hash -t requires at least one argument. */ - if (list == 0 && list_targets) + if (list == 0 && (delete || list_targets)) { - sh_needarg ("-t"); + sh_needarg (delete ? "-d" : "-t"); return (EXECUTION_FAILURE); } diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 22d90a5cd..79ab93398 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -187,7 +187,7 @@ extglob_skipname (pat, dname, flags) int flags; { char *pp, *pe, *t, *se; - int n, r, negate, wild; + int n, r, negate, wild, nullpat; negate = *pat == '!'; wild = *pat == '*' || *pat == '?'; @@ -214,6 +214,11 @@ extglob_skipname (pat, dname, flags) return r; } + /* Is the extglob pattern between the parens the null pattern? The null + pattern can match nothing, so should we check any remaining portion of + the pattern? */ + nullpat = pe >= (pat + 2) && pe[-2] == '(' && pe[-1] == ')'; + /* check every subpattern */ while (t = glob_patscan (pp, pe, '|')) { @@ -305,7 +310,7 @@ wextglob_skipname (pat, dname, flags) { #if EXTENDED_GLOB wchar_t *pp, *pe, *t, n, *se; - int r, negate, wild; + int r, negate, wild, nullpat; negate = *pat == L'!'; wild = *pat == L'*' || *pat == L'?'; @@ -323,6 +328,11 @@ wextglob_skipname (pat, dname, flags) return r; } + /* Is the extglob pattern between the parens the null pattern? The null + pattern can match nothing, so should we check any remaining portion of + the pattern? */ + nullpat = pe >= (pat + 2) && pe[-2] == L'(' && pe[-1] == L')'; + /* check every subpattern */ while (t = glob_patscan_wc (pp, pe, '|')) { diff --git a/parse.y b/parse.y index 3ff87bccc..07e6e3e44 100644 --- a/parse.y +++ b/parse.y @@ -2557,12 +2557,14 @@ next_alias_char: if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE && pushed_string_list->flags != PSH_DPAREN && (parser_state & PST_COMMENT) == 0 && + (parser_state & PST_ENDALIAS) == 0 && /* only once */ shell_input_line_index > 0 && - shell_input_line[shell_input_line_index-1] != ' ' && + shellblank (shell_input_line[shell_input_line_index-1]) == 0 && shell_input_line[shell_input_line_index-1] != '\n' && shellmeta (shell_input_line[shell_input_line_index-1]) == 0 && (current_delimiter (dstack) != '\'' && current_delimiter (dstack) != '"')) { + parser_state |= PST_ENDALIAS; return ' '; /* END_ALIAS */ } #endif @@ -2571,6 +2573,7 @@ pop_alias: /* This case works for PSH_DPAREN as well */ if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE) { + parser_state &= ~PST_ENDALIAS; pop_string (); uc = shell_input_line[shell_input_line_index]; if (uc) diff --git a/parser.h b/parser.h index 54dd2c889..59bddacaf 100644 --- a/parser.h +++ b/parser.h @@ -1,7 +1,7 @@ /* parser.h -- Everything you wanted to know about the parser, but were afraid to ask. */ -/* Copyright (C) 1995-2010 Free Software Foundation, Inc. +/* Copyright (C) 1995-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -47,6 +47,7 @@ #define PST_REPARSE 0x040000 /* re-parsing in parse_string_to_word_list */ #define PST_REDIRLIST 0x080000 /* parsing a list of redirections preceding a simple command name */ #define PST_COMMENT 0x100000 /* parsing a shell comment; used by aliases */ +#define PST_ENDALIAS 0x200000 /* just finished expanding and consuming an alias */ /* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ struct dstack { diff --git a/tests/alias.right b/tests/alias.right index 3ab9a7171..398c69e65 100644 --- a/tests/alias.right +++ b/tests/alias.right @@ -30,3 +30,4 @@ a b a a b ok 3 ok 4 +bar diff --git a/tests/alias4.sub b/tests/alias4.sub index 6ea513a17..b205fee75 100644 --- a/tests/alias4.sub +++ b/tests/alias4.sub @@ -68,3 +68,10 @@ long_comment text after # comment comment foo bar + +# alias ending in a tab +alias foo="\ + echo \"bar\" \ + " + +foo diff --git a/variables.c b/variables.c index 610629abb..f6346eb59 100644 --- a/variables.c +++ b/variables.c @@ -4775,7 +4775,6 @@ make_env_array_from_var_list (vars) using the cached exportstr... */ list[list_index] = USE_EXPORTSTR ? savestring (value) : mk_env_string (var->name, value, function_p (var)); - if (USE_EXPORTSTR == 0) SAVE_EXPORTSTR (var, list[list_index]); -- 2.47.2