From 1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 9 Feb 2008 05:48:42 +0000 Subject: test: fix mishandling of 'test ! arg1 op arg2 more args'; add testsuite --- coreutils/test.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'coreutils/test.c') diff --git a/coreutils/test.c b/coreutils/test.c index a30a5087d..22dadac0e 100644 --- a/coreutils/test.c +++ b/coreutils/test.c @@ -555,7 +555,7 @@ int test_main(int argc, char **argv) { int res; const char *arg0; - bool _off; + bool negate = 0; arg0 = bb_basename(argv[0]); if (arg0[0] == '[') { @@ -578,9 +578,8 @@ int test_main(int argc, char **argv) INIT_S(); res = setjmp(leaving); - if (res) { + if (res) goto ret; - } /* resetting ngroups is probably unnecessary. it will * force a new call to getgroups(), which prevents using @@ -592,34 +591,40 @@ int test_main(int argc, char **argv) */ ngroups = 0; + //argc--; + argv++; + /* Implement special cases from POSIX.2, section 4.62.4 */ - if (argc == 1) { + if (!argv[0]) { /* "test" */ res = 1; goto ret; } - if (argc == 2) { - res = (*argv[1] == '\0'); + if (LONE_CHAR(argv[0], '!') && argv[1]) { + negate = 1; + //argc--; + argv++; + } + if (!argv[1]) { /* "test [!] arg" */ + res = (*argv[0] == '\0'); goto ret; } - - /* remember if we saw argc==4 which wants *no* '!' test */ - _off = argc - 4; - if (_off ? (LONE_CHAR(argv[1], '!')) - : (argv[1][0] != '!' || argv[1][1] != '\0') - ) { - if (argc == 3) { - res = (*argv[2] != '\0'); - goto ret; - } - - t_lex(argv[2 + _off]); + if (argv[2] && !argv[3]) { + t_lex(argv[1]); if (t_wp_op && t_wp_op->op_type == BINOP) { - t_wp = &argv[1 + _off]; - res = (binop() == _off); + /* "test [!] arg1 arg2" */ + t_wp = &argv[0]; + res = (binop() == 0); goto ret; } } - t_wp = &argv[1]; + + /* Some complex expression. Undo '!' removal */ + if (negate) { + negate = 0; + //argc++; + argv--; + } + t_wp = &argv[0]; res = !oexpr(t_lex(*t_wp)); if (*t_wp != NULL && *++t_wp != NULL) { @@ -628,5 +633,5 @@ int test_main(int argc, char **argv) } ret: DEINIT_S(); - return res; + return negate ? !res : res; } -- cgit v1.2.3