test: fix mishandling of "test '(' = '('" and similar

function                                             old     new   delta
test_main                                            246     350    +104

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2014-07-01 14:16:28 +02:00
parent d32fc647d7
commit 98654b995b
2 changed files with 55 additions and 34 deletions

View File

@ -826,7 +826,6 @@ int test_main(int argc, char **argv)
{ {
int res; int res;
const char *arg0; const char *arg0;
// bool negate = 0;
arg0 = bb_basename(argv[0]); arg0 = bb_basename(argv[0]);
if (arg0[0] == '[') { if (arg0[0] == '[') {
@ -844,6 +843,7 @@ int test_main(int argc, char **argv)
} }
argv[argc] = NULL; argv[argc] = NULL;
} }
/* argc is unused after this point */
/* We must do DEINIT_S() prior to returning */ /* We must do DEINIT_S() prior to returning */
INIT_S(); INIT_S();
@ -862,43 +862,45 @@ int test_main(int argc, char **argv)
*/ */
/*ngroups = 0; - done by INIT_S() */ /*ngroups = 0; - done by INIT_S() */
//argc--;
argv++; argv++;
args = argv;
/* Implement special cases from POSIX.2, section 4.62.4 */ /* Implement special cases from POSIX.2, section 4.62.4.
if (!argv[0]) { /* "test" */ * Testcase: "test '(' = '('"
res = 1; * The general parser would misinterpret '(' as group start.
goto ret; */
} if (1) {
#if 0 int negate = 0;
// Now it's fixed in the parser and should not be needed again:
if (LONE_CHAR(argv[0], '!') && argv[1]) { if (!argv[0]) {
negate = 1; /* "test" */
//argc--; res = 1;
argv++; goto ret_special;
} }
if (!argv[1]) { /* "test [!] arg" */ if (!argv[1]) {
res = (*argv[0] == '\0'); /* "test [!] arg" */
goto ret; res = (argv[0][0] == '\0');
} goto ret_special;
if (argv[2] && !argv[3]) { }
check_operator(argv[1]); if (argv[2] && !argv[3]) {
if (last_operator->op_type == BINOP) { check_operator(argv[1]);
/* "test [!] arg1 <binary_op> arg2" */ if (last_operator->op_type == BINOP) {
args = argv; /* "test [!] arg1 <binary_op> arg2" */
res = (binop() == 0); args = argv;
goto ret; res = (binop() == 0);
ret_special:
/* If there was leading "!" op... */
res ^= negate;
goto ret;
}
}
if (LONE_CHAR(argv[0], '!')) {
argv++;
negate ^= 1;
goto again;
} }
} }
/* Some complex expression. Undo '!' removal */
if (negate) {
negate = 0;
//argc++;
argv--;
}
#endif
args = argv;
res = !oexpr(check_operator(*args)); res = !oexpr(check_operator(*args));
if (*args != NULL && *++args != NULL) { if (*args != NULL && *++args != NULL) {
@ -911,6 +913,5 @@ int test_main(int argc, char **argv)
} }
ret: ret:
DEINIT_S(); DEINIT_S();
// return negate ? !res : res;
return res; return res;
} }

View File

@ -76,4 +76,24 @@ testing "test ! a = b -a ! c = d: should be true (0)" \
"0\n" \ "0\n" \
"" "" "" ""
testing "test '!' = '!': should be true (0)" \
"busybox test '!' = '!'; echo \$?" \
"0\n" \
"" ""
testing "test '(' = '(': should be true (0)" \
"busybox test '(' = '('; echo \$?" \
"0\n" \
"" ""
testing "test '!' '!' = '!': should be false (1)" \
"busybox test '!' '!' = '!'; echo \$?" \
"1\n" \
"" ""
testing "test '!' '(' = '(': should be false (1)" \
"busybox test '!' '(' = '('; echo \$?" \
"1\n" \
"" ""
exit $FAILCOUNT exit $FAILCOUNT