From cb596a55d921cb638a3cf0ede3ee60ae13728c10 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 27 May 2015 21:25:55 +0100 Subject: 35306: "test -z \(" failed due to parse confusion --- ChangeLog | 3 +++ Src/parse.c | 25 +++++++++++++++++-------- Test/C02cond.ztst | 14 ++++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d12275f41..625fd0160 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2015-05-27 Peter Stephenson + * 35306: Src/parse.c, Test/C02cond.ztst: "test -z \(" + failed owing to overeager parsing. + * unposted: Config/version.mk: 5.0.7-dev-4. 2015-05-27 Daniel Hahler diff --git a/Src/parse.c b/Src/parse.c index 06cea744e..c932851d9 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2212,13 +2212,14 @@ par_cond_2(void) { char *s1, *s2, *s3; int dble = 0; + int n_testargs = (condlex == testlex) ? arrlen(testargs) + 1 : 0; - if (condlex == testlex) { + if (n_testargs) { /* See the description of test in POSIX 1003.2 */ if (tok == NULLTOK) /* no arguments: false */ return par_cond_double(dupstring("-n"), dupstring("")); - if (!*testargs) { + if (n_testargs == 1) { /* one argument: [ foo ] is equivalent to [ -n foo ] */ s1 = tokstr; condlex(); @@ -2227,7 +2228,7 @@ par_cond_2(void) return par_cond_double(s1, dupstring("1")); return par_cond_double(dupstring("-n"), s1); } - if (testargs[1]) { + if (n_testargs > 2) { /* three arguments: if the second argument is a binary operator, * * perform that binary test on the first and the third argument */ if (!strcmp(*testargs, "=") || @@ -2253,7 +2254,7 @@ par_cond_2(void) * In "test" compatibility mode, "! -a ..." and "! -o ..." * are treated as "[string] [and] ..." and "[string] [or] ...". */ - if (!(condlex == testlex && *testargs && + if (!(n_testargs > 1 && (!strcmp(*testargs, "-a") || !strcmp(*testargs, "-o")))) { condlex(); @@ -2277,19 +2278,27 @@ par_cond_2(void) } s1 = tokstr; dble = (s1 && *s1 == '-' - && (condlex != testlex + && (!n_testargs || strspn(s1+1, "abcdefghknoprstuwxzLONGS") == 1) && !s1[2]); if (tok != STRING) { /* Check first argument for [[ STRING ]] re-interpretation */ if (s1 /* tok != DOUTBRACK && tok != DAMPER && tok != DBAR */ - && tok != LEXERR && (!dble || condlex == testlex)) { + && tok != LEXERR && (!dble || n_testargs)) { condlex(); return par_cond_double(dupstring("-n"), s1); } else YYERROR(ecused); } condlex(); + if (n_testargs == 2 && tok != STRING && tokstr && s1[0] == '-') { + /* + * Something like "test -z" followed by a token. + * We'll turn the token into a string (we've also + * checked it does have a string representation). + */ + tok = STRING; + } if (tok == INANG || tok == OUTANG) { enum lextok xtok = tok; condlex(); @@ -2308,7 +2317,7 @@ par_cond_2(void) * mean we have to go back and fix up the first one */ if (tok != LEXERR) { - if (!dble || condlex == testlex) + if (!dble || n_testargs) return par_cond_double(dupstring("-n"), s1); else return par_cond_multi(s1, newlinklist()); @@ -2316,7 +2325,7 @@ par_cond_2(void) YYERROR(ecused); } s2 = tokstr; - if (condlex != testlex) + if (!n_testargs) dble = (s2 && *s2 == '-' && !s2[2]); incond++; /* parentheses do globbing */ condlex(); diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 6581b9d6b..02fa4d473 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -374,6 +374,20 @@ F:Failures in these cases do not indicate a problem in the shell. >foo is empty >foo is full + test -z \( || print Not zero 1 + test -z \< || print Not zero 2 + test -n \( && print Not zero 3 + test -n \) && print Not zero 4 + [ -n \> ] && print Not zero 5 + [ -n \! ] && print Not zero 6 +0:test with two arguments and a token +>Not zero 1 +>Not zero 2 +>Not zero 3 +>Not zero 4 +>Not zero 5 +>Not zero 6 + %clean # This works around a bug in rm -f in some versions of Cygwin chmod 644 unmodish -- cgit 1.4.1