diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-09 05:48:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-09 05:48:42 +0000 |
commit | 1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e (patch) | |
tree | 6949b702f7751c00b72bb24e1af7ca70c9f9c961 /coreutils | |
parent | 6d52c1ee24f77690c932dfe8456dfa31e8808f4c (diff) | |
download | busybox-w32-1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e.tar.gz busybox-w32-1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e.tar.bz2 busybox-w32-1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e.zip |
test: fix mishandling of 'test ! arg1 op arg2 more args'; add testsuite
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/test.c | 49 |
1 files changed, 27 insertions, 22 deletions
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) | |||
555 | { | 555 | { |
556 | int res; | 556 | int res; |
557 | const char *arg0; | 557 | const char *arg0; |
558 | bool _off; | 558 | bool negate = 0; |
559 | 559 | ||
560 | arg0 = bb_basename(argv[0]); | 560 | arg0 = bb_basename(argv[0]); |
561 | if (arg0[0] == '[') { | 561 | if (arg0[0] == '[') { |
@@ -578,9 +578,8 @@ int test_main(int argc, char **argv) | |||
578 | INIT_S(); | 578 | INIT_S(); |
579 | 579 | ||
580 | res = setjmp(leaving); | 580 | res = setjmp(leaving); |
581 | if (res) { | 581 | if (res) |
582 | goto ret; | 582 | goto ret; |
583 | } | ||
584 | 583 | ||
585 | /* resetting ngroups is probably unnecessary. it will | 584 | /* resetting ngroups is probably unnecessary. it will |
586 | * force a new call to getgroups(), which prevents using | 585 | * force a new call to getgroups(), which prevents using |
@@ -592,34 +591,40 @@ int test_main(int argc, char **argv) | |||
592 | */ | 591 | */ |
593 | ngroups = 0; | 592 | ngroups = 0; |
594 | 593 | ||
594 | //argc--; | ||
595 | argv++; | ||
596 | |||
595 | /* Implement special cases from POSIX.2, section 4.62.4 */ | 597 | /* Implement special cases from POSIX.2, section 4.62.4 */ |
596 | if (argc == 1) { | 598 | if (!argv[0]) { /* "test" */ |
597 | res = 1; | 599 | res = 1; |
598 | goto ret; | 600 | goto ret; |
599 | } | 601 | } |
600 | if (argc == 2) { | 602 | if (LONE_CHAR(argv[0], '!') && argv[1]) { |
601 | res = (*argv[1] == '\0'); | 603 | negate = 1; |
604 | //argc--; | ||
605 | argv++; | ||
606 | } | ||
607 | if (!argv[1]) { /* "test [!] arg" */ | ||
608 | res = (*argv[0] == '\0'); | ||
602 | goto ret; | 609 | goto ret; |
603 | } | 610 | } |
604 | 611 | if (argv[2] && !argv[3]) { | |
605 | /* remember if we saw argc==4 which wants *no* '!' test */ | 612 | t_lex(argv[1]); |
606 | _off = argc - 4; | ||
607 | if (_off ? (LONE_CHAR(argv[1], '!')) | ||
608 | : (argv[1][0] != '!' || argv[1][1] != '\0') | ||
609 | ) { | ||
610 | if (argc == 3) { | ||
611 | res = (*argv[2] != '\0'); | ||
612 | goto ret; | ||
613 | } | ||
614 | |||
615 | t_lex(argv[2 + _off]); | ||
616 | if (t_wp_op && t_wp_op->op_type == BINOP) { | 613 | if (t_wp_op && t_wp_op->op_type == BINOP) { |
617 | t_wp = &argv[1 + _off]; | 614 | /* "test [!] arg1 <binary_op> arg2" */ |
618 | res = (binop() == _off); | 615 | t_wp = &argv[0]; |
616 | res = (binop() == 0); | ||
619 | goto ret; | 617 | goto ret; |
620 | } | 618 | } |
621 | } | 619 | } |
622 | t_wp = &argv[1]; | 620 | |
621 | /* Some complex expression. Undo '!' removal */ | ||
622 | if (negate) { | ||
623 | negate = 0; | ||
624 | //argc++; | ||
625 | argv--; | ||
626 | } | ||
627 | t_wp = &argv[0]; | ||
623 | res = !oexpr(t_lex(*t_wp)); | 628 | res = !oexpr(t_lex(*t_wp)); |
624 | 629 | ||
625 | if (*t_wp != NULL && *++t_wp != NULL) { | 630 | if (*t_wp != NULL && *++t_wp != NULL) { |
@@ -628,5 +633,5 @@ int test_main(int argc, char **argv) | |||
628 | } | 633 | } |
629 | ret: | 634 | ret: |
630 | DEINIT_S(); | 635 | DEINIT_S(); |
631 | return res; | 636 | return negate ? !res : res; |
632 | } | 637 | } |