diff --git a/trip.rc b/trip.rc index 104504e..d0b6940 100644 --- a/trip.rc +++ b/trip.rc @@ -718,3 +718,12 @@ submatch 'flag xx' 'usage: flag f [ + | - ]' 'flag wrong first arg' submatch 'flag x x' 'usage: flag f [ + | - ]' 'flag wrong second arg' submatch 'flag c && echo yes' yes 'flag c' submatch 'flag x +; flag x -' 'flag x -' 'setting x flag' + +# test for cmdarg exception leak in various nodes +$rc -c 'foo=<{true}' || fail 'cmdarg leak in nAssign' +$rc -c 'for(i in <{true}) echo $i >/dev/null' || fail 'cmdarg leak in nForin' +$rc -c 'foo=<{true} echo -n' || fail 'cmdarg leak in nPre' +$rc -c 'fn foo { cat <{true} }' || fail 'cmdarg leak in nNewfn' +$rc -c 'fn <{true} { }' || fail 'cmdarg leak in nRmfn' +$rc -c '~ <{true} /dev/fd/*' || fail 'cmdarg leak in nMatch' +$rc -c 'switch (<{true}) { case *; }' || fail 'cmdarg leak in nSwitch' diff --git a/walk.c b/walk.c index fef8209..bbadb19 100644 --- a/walk.c +++ b/walk.c @@ -138,7 +138,8 @@ top: sigchk(); break; } case nForin: { - List *l, *var = glom(n->u[0].p); + List *var = glom(n->u[0].p); + List *l = listcpy(glob(glom(n->u[1].p)), nalloc); Jbwrap break_jb; Edata break_data; Estack break_stack; @@ -147,7 +148,7 @@ top: sigchk(); break_data.jb = &break_jb; except(eBreak, break_data, &break_stack); - for (l = listcpy(glob(glom(n->u[1].p)), nalloc); l != NULL; l = l->n) { + for (; l != NULL; l = l->n) { Edata iter_data; Estack iter_stack; assign(var, word(l->w, NULL), FALSE); @@ -157,6 +158,7 @@ top: sigchk(); unexcept(eArena); } unexcept(eBreak); + pop_cmdarg(TRUE); break; } case nSubshell: @@ -170,6 +172,7 @@ top: sigchk(); if (n->u[0].p == NULL) rc_error("null variable name"); assign(glom(n->u[0].p), glob(glom(n->u[1].p)), FALSE); + pop_cmdarg(TRUE); break; case nPipe: dopipe(n); @@ -185,6 +188,7 @@ top: sigchk(); l = l->n; } set(TRUE); + pop_cmdarg(TRUE); break; } case nRmfn: { @@ -196,6 +200,7 @@ top: sigchk(); l = l->n; } set(TRUE); + pop_cmdarg(TRUE); break; } case nDup: @@ -206,6 +211,7 @@ top: sigchk(); if (dashex) fprint(2, (a != NULL && a->n != NULL) ? "~ (%L) %L\n" : "~ %L %L\n", a, " ", b, " "); set(lmatch(a, b)); + pop_cmdarg(TRUE); break; } case nSwitch: { @@ -213,8 +219,10 @@ top: sigchk(); while (1) { do { n = n->u[1].p; - if (n == NULL) + if (n == NULL) { + pop_cmdarg(TRUE); return istrue(); + } } while (n->u[0].p == NULL || n->u[0].p->type != nCase); if (lmatch(v, glom(n->u[0].p->u[0].p))) { for (n = n->u[1].p; n != NULL && (n->u[0].p == NULL || n->u[0].p->type != nCase); n = n->u[1].p) @@ -222,6 +230,7 @@ top: sigchk(); break; } } + pop_cmdarg(TRUE); break; } case nPre: { @@ -250,6 +259,7 @@ top: sigchk(); walk(n->u[1].p, parent); varrm(v->w, TRUE); unexcept(eVarstack); + pop_cmdarg(TRUE); } } else panic("unexpected node in preredir section of walk");