Bug 4832

Summary: test builtin chokes on bare "!"
Product: Busybox Reporter: Michael Tokarev <mjt+busybox>
Component: OtherAssignee: unassigned
Status: RESOLVED FIXED    
Severity: minor CC: busybox-cvs, zurgunt
Priority: P5    
Version: 1.19.x   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Host: Target:
Build:

Description Michael Tokarev 2012-03-02 16:39:29 UTC
To reproduce:

$ busybox sh -xc 'test !'
+ test !
Segmentation fault

It happens on x64 this way, on i386 it succeeds but only because there's more room in argv vector, see below.

In coreutils/test.c, we see:

 test_main()
 -> oexpr(UNOT)
  -> aexpr(UNOT)
   -> nexpr(UNOT)

static number_t nexpr(enum token n)
{
at entry, *args points to the last NULL argv element.
        number_t res;

        nest_msg(">nexpr(%s)\n", TOKSTR[n]);
        if (n == UNOT) {
                n = check_operator(*++args);
                                   ^^^^^^^
we increment args, it points past the array.  check_operator retursn EOI.
                if (n == EOI) {
                        /* special case: [ ! ], [ a -a ! ] are valid */
                        /* IOW, "! ARG" may miss ARG */
                        unnest_msg("<nexpr:1 (!EOI)\n");
                        return 1;
                        ^^^^^^^^^ we are here

And back in aexpr(), we have:

static number_t aexpr(enum token n)
{
        number_t res;

        nest_msg(">aexpr(%s)\n", TOKSTR[n]);
        res = nexpr(n);
              ^^^^^^^ we called this nexpr, which returned
        dbg_msg("aexpr: nexpr:%lld, next args:%s\n", res, args[1]);
        if (check_operator(*++args) == BAND) {
                          ^^^^^^^^^
And there, we're referencing next-after-last argv element.

Maybe nexpr should not increment args in case of EOI ?

Thanks,

/mjt
Comment 1 Denys Vlasenko 2012-03-08 02:51:02 UTC
Thanks for reporting.

Fixed in git:

http://git.busybox.net/busybox/commit/?id=07fcaab595e9029ebe37f5240a10038c493af545