From fd2ca229ddfc913f14f3b4b27fe8dcb25a5bba1d Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 2 Dec 2016 16:01:04 +0000 Subject: 40067: internal: Document 'cmatcher', parse_cmatcher(), 'comptoend', unsetparam_pm(), and getindex(). --- Src/Zle/comp.h | 4 +++- Src/Zle/complete.c | 12 ++++++++++-- Src/params.c | 18 +++++++++++++++++- 3 files changed, 30 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index 3711fde29..3e9834560 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -153,7 +153,9 @@ struct cmatcher { Cpattern line; /* what matches on the line */ int llen; /* length of line pattern */ Cpattern word; /* what matches in the word */ - int wlen; /* length of word pattern */ + int wlen; /* length of word pattern, or: + -1: word pattern is one asterisk + -2: word pattern is two asterisks */ Cpattern left; /* left anchor */ int lalen; /* length of left anchor */ Cpattern right; /* right anchor */ diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 7980518b7..48fcd4751 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -67,7 +67,7 @@ char *compiprefix, *compexact, *compexactstr, *comppatinsert, - *comptoend, + *comptoend, /* compstate[to_end]; populates 'movetoend' */ *compoldlist, *compoldins, *compvared; @@ -227,7 +227,15 @@ cpcpattern(Cpattern o) return r; } -/* Parse a string for matcher control, containing multiple matchers. */ +/* + * Parse a string for matcher control, containing multiple matchers. + * + * 's' is the string to be parsed. + * + * 'name' is the name of the builtin from which this is called, for errors. + * + * Return 'pcm_err' on error; a NULL return value means ... + */ /**/ mod_export Cmatcher diff --git a/Src/params.c b/Src/params.c index aa8b196bd..21a910190 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1761,6 +1761,18 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, return r; } +/* + * Parse a subscript. + * + * pptr: In/Out parameter. On entry, *ptr points to a "[foo]" string. On exit + * it will point one past the closing bracket. + * + * v: In/Out parameter. Its .start and .end members (at least) will be updated + * with the parsed indices. + * + * flags: can be either SCANPM_DQUOTED or zero. Other bits are not used. + */ + /**/ int getindex(char **pptr, Value v, int flags) @@ -3245,7 +3257,11 @@ unsetparam(char *s) unqueue_signals(); } -/* Unset a parameter */ +/* Unset a parameter + * + * altflag: if true, don't remove pm->ename from the environment + * exp: See stdunsetfn() + */ /**/ mod_export int -- cgit v1.2.3 From 334ed65e2765062a449897d70925255929eae8a8 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 2 Dec 2016 12:08:26 +0000 Subject: 40068: Abort execution when setuid/setgid fail. The incumbent code would print an error message and continue execution with the previous uid/gid values, not even setting lastval: % UID=42 id -u; echo $? zsh: failed to change user ID: operation not permitted 1000 0 % --- ChangeLog | 3 +++ Src/params.c | 8 ++++---- Test/B02typeset.ztst | 10 ++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 20574d17e..eb29a06cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-12-03 Daniel Shahaf + * 40068: Src/params.c, Test/B02typeset.ztst: Abort execution + when setuid/setgid fail. + * 40067: Src/Zle/comp.h, Src/Zle/complete.c, Src/params.c: internal: Document 'cmatcher', parse_cmatcher(), 'comptoend', unsetparam_pm(), and getindex(). diff --git a/Src/params.c b/Src/params.c index 21a910190..c64d7486b 100644 --- a/Src/params.c +++ b/Src/params.c @@ -4077,7 +4077,7 @@ uidsetfn(UNUSED(Param pm), zlong x) { #ifdef HAVE_SETUID if (setuid((uid_t)x)) - zwarn("failed to change user ID: %e", errno); + zerr("failed to change user ID: %e", errno); #endif } @@ -4098,7 +4098,7 @@ euidsetfn(UNUSED(Param pm), zlong x) { #ifdef HAVE_SETEUID if (seteuid((uid_t)x)) - zwarn("failed to change effective user ID: %e", errno); + zerr("failed to change effective user ID: %e", errno); #endif } @@ -4119,7 +4119,7 @@ gidsetfn(UNUSED(Param pm), zlong x) { #ifdef HAVE_SETUID if (setgid((gid_t)x)) - zwarn("failed to change group ID: %e", errno); + zerr("failed to change group ID: %e", errno); #endif } @@ -4140,7 +4140,7 @@ egidsetfn(UNUSED(Param pm), zlong x) { #ifdef HAVE_SETEUID if (setegid((gid_t)x)) - zwarn("failed to change effective group ID: %e", errno); + zerr("failed to change effective group ID: %e", errno); #endif } diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 6d85a63fe..9c56c7e5e 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -711,3 +711,13 @@ typeset isreadonly=still 1:typeset returns status 1 if setting readonly variable ?(eval):2: read-only variable: isreadonly + + if (( UID )); then + UID=$((UID+1)) date; echo "Status is printed, $?" + else + ZTST_skip="cannot test setuid error when tests run as superuser" + fi +0:when cannot change UID, the command isn't run +# 'date' did not run. +>Status is printed, 1 +?(eval):2: failed to change user ID: operation not permitted -- cgit v1.2.3 From a409adc33bc17c9538a5afbdcb3c643b82cc6ce9 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 3 Dec 2016 15:00:46 -0800 Subject: 40071: change Dash back to "-" before evaluating named directory expansions --- ChangeLog | 7 ++++++- Src/subst.c | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index eb29a06cb..cc6e84dc5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-12-03 Barton E. Schaefer + + * 40071: Src/subst.c: change Dash back to "-" before evaluating + named directory expansions + 2016-12-03 Daniel Shahaf * 40068: Src/params.c, Test/B02typeset.ztst: Abort execution @@ -54,7 +59,7 @@ * 40036: Completion/Debian/Command/_bts: Complete removal syntaxes correctly. -2016-11-29 Barton E. Schaefer +2016-11-29 Barton E. Schaefer * 40034: Src/subst.c: clear badcshglob when ignoring errors diff --git a/Src/subst.c b/Src/subst.c index 06d2c9ea9..64b440027 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -650,6 +650,8 @@ filesubstr(char **namptr, int assign) char *ptr, *tmp, *res, *ptr2; int val; + if (str[1] == Dash) + str[1] = '-'; val = zstrtol(str + 1, &ptr, 10); if (isend(str[1])) { /* ~ */ *namptr = dyncat(home ? home : "", str + 1); -- cgit v1.2.3 From c03228f9ed28dfaa9ded49eabb93c04def5ac547 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 5 Dec 2016 11:21:01 +0000 Subject: Extra case for ERR_RETURN and ERR_EXIT. Don't trigger just because status is non-zero at end of complex shell construct as this may be a case we've already suppressed. --- ChangeLog | 6 +++++ Src/exec.c | 10 +++++++- Src/loop.c | 6 +++++ Src/zsh.h | 1 + Test/C03traps.ztst | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 1 deletion(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 67f8c7687..c0afd0773 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-12-05 Peter Stephenson + + * 40096: Src/exec.c, Src/loop.c, Src/zsh.h, Test/C03traps.ztst: + Don't trigger ERR_EXIT or ERR_RETURN on non-zero status after + shell construct. + 2016-12-04 Daniel Shahaf * unposted: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: diff --git a/Src/exec.c b/Src/exec.c index f544a33e7..6e197ddf2 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -46,6 +46,11 @@ enum { /**/ int noerrexit; +/* used to suppress ERREXIT for one occurrence */ + +/**/ +int this_noerrexit; + /* * noerrs = 1: suppress error messages * noerrs = 2: don't set errflag on parse error, either @@ -1238,7 +1243,8 @@ execlist(Estate state, int dont_change_job, int exiting) } while (wc_code(code) == WC_LIST && !breaks && !retflag && !errflag) { int donedebug; - int this_noerrexit = 0, this_donetrap = 0; + int this_donetrap = 0; + this_noerrexit = 0; ltype = WC_LIST_TYPE(code); csp = cmdsp; @@ -5813,6 +5819,7 @@ execsave(void) es->trapisfunc = trapisfunc; es->traplocallevel = traplocallevel; es->noerrs = noerrs; + es->this_noerrexit = this_noerrexit; es->underscore = ztrdup(zunderscore); es->next = exstack; exstack = es; @@ -5847,6 +5854,7 @@ execrestore(void) trapisfunc = en->trapisfunc; traplocallevel = en->traplocallevel; noerrs = en->noerrs; + this_noerrexit = en->this_noerrexit; setunderscore(en->underscore); zsfree(en->underscore); free(en); diff --git a/Src/loop.c b/Src/loop.c index 367c0df5c..ae87b2f5f 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -208,6 +208,7 @@ execfor(Estate state, int do_exec) loops--; simple_pline = old_simple_pline; state->pc = end; + this_noerrexit = 1; return lastval; } @@ -335,6 +336,7 @@ execselect(Estate state, UNUSED(int do_exec)) loops--; simple_pline = old_simple_pline; state->pc = end; + this_noerrexit = 1; return lastval; } @@ -472,6 +474,7 @@ execwhile(Estate state, UNUSED(int do_exec)) popheap(); loops--; state->pc = end; + this_noerrexit = 1; return lastval; } @@ -523,6 +526,7 @@ execrepeat(Estate state, UNUSED(int do_exec)) loops--; simple_pline = old_simple_pline; state->pc = end; + this_noerrexit = 1; return lastval; } @@ -573,6 +577,7 @@ execif(Estate state, int do_exec) lastval = 0; } state->pc = end; + this_noerrexit = 1; return lastval; } @@ -682,6 +687,7 @@ execcase(Estate state, int do_exec) if (!anypatok) lastval = 0; + this_noerrexit = 1; return lastval; } diff --git a/Src/zsh.h b/Src/zsh.h index dae2b2459..f2c030004 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1070,6 +1070,7 @@ struct execstack { int trapisfunc; int traplocallevel; int noerrs; + int this_noerrexit; char *underscore; }; diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index c3bedb06c..e94fb6f85 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -626,6 +626,76 @@ F:Must be tested with a top-level script rather than source or function >before-out >before-in + (setopt err_exit + for x in y; do + false && true + done + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of for +>OK + + (setopt err_exit + integer x=0 + while (( ! x++ )); do + false && true + done + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of while +>OK + + (setopt err_exit + repeat 1; do + false && true + done + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of repeat +>OK + + (setopt err_exit + if true; then + false && true + fi + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of if +>OK + + (setopt err_exit + for x in y; do + false + done + print OK + ) +1:ERR_EXIT triggered by status 1 within for + + (setopt err_exit + integer x=0 + while (( ! x++ )); do + false + done + print OK + ) +1:ERR_EXIT triggered by status 1 within while + + (setopt err_exit + repeat 1; do + false + done + print OK + ) +1:ERR_EXIT triggered by status 1 within repeat + + (setopt err_exit + if true; then + false + fi + print OK + ) +1:ERR_EXIT triggered by status 1 within if + if zmodload zsh/system 2>/dev/null; then ( trap 'echo TERM; exit 2' TERM -- cgit v1.2.3 From 0e4aa6f2f64fb276537adecfe755a752a3fcccb1 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 5 Dec 2016 12:29:23 +0000 Subject: Additional case for ERR_RETURN and ERR_EXIT. Don't trigger just because status is non-zero at end of current shell group. --- ChangeLog | 3 +++ Src/exec.c | 1 + Test/C03traps.ztst | 17 +++++++++++++++++ 3 files changed, 21 insertions(+) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index c0afd0773..b912821e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-12-05 Peter Stephenson + * 40097: Src/exec.c, Test/C03traps.ztst: Don't trigger ERR_EXIT + or ERR_RETURN on non-zero status after current shell group, either. + * 40096: Src/exec.c, Src/loop.c, Src/zsh.h, Test/C03traps.ztst: Don't trigger ERR_EXIT or ERR_RETURN on non-zero status after shell construct. diff --git a/Src/exec.c b/Src/exec.c index 6e197ddf2..a439aec7f 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -429,6 +429,7 @@ execcursh(Estate state, int do_exec) cmdpop(); state->pc = end; + this_noerrexit = 1; return lastval; } diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index e94fb6f85..dc386a44e 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -661,6 +661,15 @@ F:Must be tested with a top-level script rather than source or function print OK ) 0:ERR_EXIT not triggered by status 1 at end of if +>OK + + (setopt err_exit + { + false && true + } + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of { } >OK (setopt err_exit @@ -696,6 +705,14 @@ F:Must be tested with a top-level script rather than source or function ) 1:ERR_EXIT triggered by status 1 within if + (setopt err_exit + { + false + } + print OK + ) +1:ERR_EXIT triggered by status 1 within { } + if zmodload zsh/system 2>/dev/null; then ( trap 'echo TERM; exit 2' TERM -- cgit v1.2.3