On Wed, Sep 04, 2013 at 11:56:29AM +1000, Herbert Xu wrote: > Harald van Dijk <harald@xxxxxxxxxxx> wrote: > > Hi, > > > > Now that Herbert fixed the reported crash in test (in a far simpler > > manner than I had suggested, which I like), I did some more testing, and > > came across one case that does not currently work, and did not work in > > the past, but is perfectly valid: > > > > $ src/dash -c 'test ! ! = !' > > src/dash: 1: test: =: unexpected operator > > Agreed. This case is now fixed by the following patch: commit 4f7e4c8201e580b9d31c09d8a484741072033c01 Author: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> Date: Sun Sep 28 18:40:18 2014 +0800 [BUILTIN] Correctly handle test ! ! = ! This patch adds a special case in testcmd for the 4-argument expression beginning with a !. Without this ! ! = ! is deemed a syntax error, which breaks POSIX. Note that this special case does not extend down into subexpressions so if ! ! = ! is used inside parentheses then a syntax error will still occur as before. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> diff --git a/ChangeLog b/ChangeLog index a466a7f..7345144 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-09-28 Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> + + * Correctly handle test ! ! = !. + 2014-09-26 Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> * Small optimisation of command -pv change. diff --git a/src/bltin/test.c b/src/bltin/test.c index baa91a5..458e9f5 100644 --- a/src/bltin/test.c +++ b/src/bltin/test.c @@ -177,7 +177,7 @@ testcmd(int argc, char **argv) { const struct t_op *op; enum token n; - int res; + int res = 1; if (*argv[0] == '[') { if (*argv[--argc] != ']') @@ -185,11 +185,12 @@ testcmd(int argc, char **argv) argv[argc] = NULL; } +recheck: argv++; argc--; if (argc < 1) - return 1; + return res; /* * POSIX prescriptions: he who wrote this deserves the Nobel @@ -209,6 +210,9 @@ testcmd(int argc, char **argv) argv[--argc] = NULL; argv++; argc--; + } else if (!strcmp(argv[0], "!")) { + res = 0; + goto recheck; } } @@ -216,7 +220,7 @@ testcmd(int argc, char **argv) eval: t_wp = argv; - res = !oexpr(n); + res ^= oexpr(n); argv = t_wp; if (argv[0] != NULL && argv[1] != NULL) Cheers, -- Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html