From 417883dfdd4a39bd882285e74f6fbe9b1aea47a3 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sat, 5 Sep 2020 16:48:17 +0200 Subject: [PATCH] Revert "Fix subshell leak for 4 special variables (re: bd3e2a80)" This reverts commit b3d37b00b0d46d434c90b4e5a3673fc3f5d5a197. While ksh's own regression test suite passed just fine, when running the modernish[*] regression tests uite, ksh either froze hard (needing SIGKILL) or threw a spurious syntax error. Cause unknown, but I'm certainly reverting until I find out. This reintroduces a subshell leak for four special variables. [*] https://github.com/modernish/modernish --- src/cmd/ksh93/bltins/typeset.c | 6 +++--- src/cmd/ksh93/sh/subshell.c | 11 +++++++++-- src/cmd/ksh93/tests/variables.sh | 14 -------------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index a1591883e..52b9c899e 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -688,7 +688,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp * Variables with internal trap/discipline functions (LC_*, LINENO, etc.) need to be * cloned, as moving them will remove the discipline function. */ - np=sh_assignok(np,1); + np=sh_assignok(np,2); } else np=sh_assignok(np,0); @@ -800,7 +800,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp if (tp->aflag && (tp->argnum>0 || (curflag!=newflag))) { if(shp->subshell) - sh_assignok(np,1); + sh_assignok(np,3); if(troot!=shp->var_tree) nv_setattr(np,newflag&~NV_ASSIGN); else @@ -1285,7 +1285,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) * Variables with internal trap/discipline functions (LC_*, LINENO, etc.) need to be * cloned, as moving them will remove the discipline function. */ - np=sh_assignok(np,1); + np=sh_assignok(np,2); } else np=sh_assignok(np,0); diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c index 5ecbc94ce..87c7d65b2 100644 --- a/src/cmd/ksh93/sh/subshell.c +++ b/src/cmd/ksh93/sh/subshell.c @@ -233,6 +233,10 @@ int nv_subsaved(register Namval_t *np) * * add == 0: Move the node pointer from the parent shell to the current virtual subshell. * add == 1: Create a copy of the node pointer in the current virtual subshell. + * add == 2: This will create a copy of the node pointer like 1, but it will disable the + * optimization for ${.sh.level}. + * add == 3: This is like 1, but it will never skip the following variables: + * ${.sh.level}, $_, ${.sh.subscript} and ${.sh.name}. */ Namval_t *sh_assignok(register Namval_t *np,int add) { @@ -244,8 +248,11 @@ Namval_t *sh_assignok(register Namval_t *np,int add) Namval_t *mpnext; Namarr_t *ap; unsigned int save; - /* don't save if told not to (see nv_restore()) or if we're in a ${ subshare; } */ - if(!sp->shpwd || shp->subshare) + /* don't bother to save if in a ${ subshare; } */ + if(sp->subshare) + return(np); + /* don't bother with this */ + if(!sp->shpwd || (add != 3 && ((add != 2 && np==SH_LEVELNOD) || np==L_ARGNOD || np==SH_SUBSCRNOD || np==SH_NAMENOD))) return(np); if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np))) { diff --git a/src/cmd/ksh93/tests/variables.sh b/src/cmd/ksh93/tests/variables.sh index f122ed5d4..0ffe75dd4 100755 --- a/src/cmd/ksh93/tests/variables.sh +++ b/src/cmd/ksh93/tests/variables.sh @@ -1011,20 +1011,6 @@ $SHELL -c ' e=$? ((e == 1)) || err_exit "Failure in making one or more special variables readonly in a subshell (exit status $e)" -# ... subshell leak test -$SHELL -c ' - errors=0 - for var - do if eval "($var=bug); [[ \${$var} == bug ]]" 2>/dev/null - then echo " $0: special variable $var leaks out of subshell" >&2 - let errors++ - fi - done - exit $((errors + 1)) -' subshell_leak_test "$@" -e=$? -((e == 1)) || err_exit "One or more special variables leak out of a subshell (exit status $e)" - # ====== # ${.sh.pid} should be the forked subshell's PID (