summaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-09 05:48:42 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-09 05:48:42 +0000
commit1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e (patch)
tree6949b702f7751c00b72bb24e1af7ca70c9f9c961 /coreutils
parent6d52c1ee24f77690c932dfe8456dfa31e8808f4c (diff)
downloadbusybox-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.c49
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}