| Summary: | test builtin chokes on bare "!" | ||
|---|---|---|---|
| Product: | Busybox | Reporter: | Michael Tokarev <mjt+busybox> |
| Component: | Other | Assignee: | 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: | |||
Thanks for reporting. Fixed in git: http://git.busybox.net/busybox/commit/?id=07fcaab595e9029ebe37f5240a10038c493af545 |
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