Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

variable exported in function in a subshell is also visible in a different subshell #7

Closed
lijog opened this issue Mar 14, 2016 · 4 comments
Assignees
Labels

Comments

@lijog
Copy link

lijog commented Mar 14, 2016

I've observed this issue in a Solaris 11 system with all the ksh93 versions(alpha, beta and the master versions) as well as in Ubuntu 14 ( ksh2012).

Here's a testcase which reproduces the issue.

# cat test1.ksh
# !/usr/bin/ksh

function proxy { 
         export MYVAR="bla" 
        child 
        unset MYVAR 
} 

function child { 
        echo "MYVAR=$MYVAR" >> /var/tmp/debug.log 
} 

function test { 
        $(child) 
        $(proxy) 
        $(child) 
} 

rm /var/tmp/debug.log 
test 
cat /var/tmp/debug.log 
# ./test1.ksh

MYVAR= 
MYVAR=bla 
MYVAR=bla <------------------------------ this should not happen 
# 

The following patch which removes an optimization fixes the issue. If there is any other patch, please let me know.

--- INIT.2012-08-01.old/src/cmd/ksh93/sh/subshell.c     2016-03-01 04:01:06.513890578 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/shsubshell.c  2016-03-01 04:02:43.617872391 -0800
@@ -260,9 +260,6 @@
        shp = sp->shp;
        dp = shp->var_tree;
-       /\* don't bother to save if in newer scope */
-       if(sp->var!=shp->var_tree && sp->var!=shp->var_base && shp->last_root==shp->var_tree)
-               return(np);
      if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
      {
              shp->last_root = ap->table;

The issue seems to be happening because of the following optimization in sh_assignok function in sh/subshell.c.


 /\* don't bother to save if in newer scope */ 
 if(sp->var!=shp->var_tree && shp->last_root==shp->var_tree) 
        return(np); 

This optimization prevents saving the variables in situations where they don't need to be restored. If we remove the optimization, the issue will go away.

@krader1961
Copy link
Contributor

Does anyone know why the proposed fix hasn't been merged? I can reproduce the failure using the provided test case using a ksh93 built from the current beta branch. The proposed fix does make the test case behave correctly. TBD is whether it affects any of the unit tests.

@kdudka
Copy link
Contributor

kdudka commented Nov 7, 2017

The patch is nearly impossible to read. Please use markdown to denote code blocks (to avoid interpreting code as markdown and to switch font to monospace).

@dannyweldon
Copy link

I just edited the comment to format the code blocks.

@kdudka
Copy link
Contributor

kdudka commented Nov 7, 2017

@dannyweldon Thanks! I do not have privileges to do it myself...

@krader1961 The proposed patch makes sense to me. It fixes the problem and does no seem to break anything else...

@krader1961 krader1961 self-assigned this Nov 9, 2017
krader1961 added a commit that referenced this issue Nov 11, 2017
siteshwar pushed a commit that referenced this issue Nov 30, 2017
McDutchie referenced this issue in ksh93/ksh Jun 11, 2020
Since we now have a shiny new POSIX compliant 'times' builtin,
we might as well use it.

src/cmd/ksh93/tests/shtests:
- Run 'times' at end of test run.
- Skip the pretty-printing until #7 is fixed.

(cherry picked from commit 2c27d9fbc239583004ec70377db98627eea5e294)
McDutchie referenced this issue in ksh93/ksh Jun 11, 2020
Since we now have a shiny new POSIX compliant 'times' builtin,
we might as well use it.

src/cmd/ksh93/tests/shtests:
- Run 'times' at end of test run.
- Skip the pretty-printing until #7 is fixed.

(cherry picked from commit 2c27d9fbc239583004ec70377db98627eea5e294)
JohnoKing added a commit to JohnoKing/ksh that referenced this issue Jun 15, 2020
This bug was originally reported by @lijog in att#7 and has been
reported again in ksh93#15. KSH does not save the state of a variable if it
is in a newer scope. This is because of an optimization in sh_assignok
first introduced in ksh93t+ 2010-05-24. Here is the code change in that
version:

                return(np);
        /* don't bother to save if in newer scope */
-       if(!(rp=shp->st.real_fun)  || !(dp=rp->sdict))
-               dp = sp->var;
-       if(np->nvenv && !nv_isattr(np,NV_MINIMAL|NV_EXPORT) && shp->last_root)
-               dp = shp->last_root;
-       if((mp=nv_search((char*)np,dp,HASH_BUCKET))!=np)
-       {
-               if(mp || !np->nvfun || np->nvfun->subshell>=sh.subshell)
-                       return(np);
-       }
+       if(sp->var!=shp->var_tree && shp->last_root==shp->var_tree)
+               return(np);
        if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
        {

This change was originally made to replace a buggier optimization.
However, the current optimization causes variables set in subshells
to wrongly affect the environment outside of the subshell, as the
variable does not get set back to its original value. This patch
simply removes the buggy optimization to fix this problem.

src/cmd/ksh93/sh/subshell.c:
 - Remove a buggy optimization that caused variables set in subshells
   to affect the environment outside of the subshell.

src/cmd/ksh93/tests/subshell.sh:
 - Add a regression test for setting variables in subshells. This
   test has to be run in a here document because it always returns
   the expected result when run directly in the regression test
   script.
JohnoKing added a commit to JohnoKing/ksh that referenced this issue Jun 15, 2020
This bug was originally reported by @lijog in att#7 and has been
reported again in ksh93#15. KSH does not save the state of a variable if it
is in a newer scope. This is because of an optimization in sh_assignok
first introduced in ksh93t+ 2010-05-24. Here is the code change in that
version:

                return(np);
        /* don't bother to save if in newer scope */
-       if(!(rp=shp->st.real_fun)  || !(dp=rp->sdict))
-               dp = sp->var;
-       if(np->nvenv && !nv_isattr(np,NV_MINIMAL|NV_EXPORT) && shp->last_root)
-               dp = shp->last_root;
-       if((mp=nv_search((char*)np,dp,HASH_BUCKET))!=np)
-       {
-               if(mp || !np->nvfun || np->nvfun->subshell>=sh.subshell)
-                       return(np);
-       }
+       if(sp->var!=shp->var_tree && shp->last_root==shp->var_tree)
+               return(np);
        if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
        {

This change was originally made to replace a buggier optimization.
However, the current optimization causes variables set in subshells
to wrongly affect the environment outside of the subshell, as the
variable does not get set back to its original value. This patch
simply removes the buggy optimization to fix this problem.

src/cmd/ksh93/sh/subshell.c:
 - Remove a buggy optimization that caused variables set in subshells
   to affect the environment outside of the subshell.

src/cmd/ksh93/tests/subshell.sh:
 - Add a regression test for setting variables in subshells. This
   test has to be run in a here document because it always returns
   the expected result when run directly in the regression test
   script.
JohnoKing added a commit to JohnoKing/ksh that referenced this issue Jun 15, 2020
This bug was originally reported by @lijog in att#7 and has been
reported again in ksh93#15. KSH does not save the state of a variable if it
is in a newer scope. This is because of an optimization in sh_assignok
first introduced in ksh93t+ 2010-05-24. Here is the code change in that
version:

                return(np);
        /* don't bother to save if in newer scope */
-       if(!(rp=shp->st.real_fun)  || !(dp=rp->sdict))
-               dp = sp->var;
-       if(np->nvenv && !nv_isattr(np,NV_MINIMAL|NV_EXPORT) && shp->last_root)
-               dp = shp->last_root;
-       if((mp=nv_search((char*)np,dp,HASH_BUCKET))!=np)
-       {
-               if(mp || !np->nvfun || np->nvfun->subshell>=sh.subshell)
-                       return(np);
-       }
+       if(sp->var!=shp->var_tree && shp->last_root==shp->var_tree)
+               return(np);
        if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
        {

This change was originally made to replace a buggier optimization.
However, the current optimization causes variables set in subshells
to wrongly affect the environment outside of the subshell, as the
variable does not get set back to its original value. This patch
simply removes the buggy optimization to fix this problem.

src/cmd/ksh93/sh/subshell.c:
 - Remove a buggy optimization that caused variables set in subshells
   to affect the environment outside of the subshell.

src/cmd/ksh93/tests/subshell.sh:
 - Add a regression test for setting variables in subshells. This
   test has to be run from the disk after being created with a here
   document because it always returns the expected result when run
   directly in the regression test script.
citrus-it added a commit to citrus-it/ast that referenced this issue Dec 30, 2020
citrus-it added a commit to citrus-it/ast that referenced this issue Dec 30, 2020
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 4, 2021
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 4, 2021
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 4, 2021
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 5, 2021
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 5, 2021
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 8, 2021
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 8, 2021
McDutchie added a commit to ksh93/ksh that referenced this issue Jan 8, 2021
ksh 93u+ has a subshell leak bug where a variable exported in
function in a subshell is also visible in a different subshell.
This is long fixed in 93u+m, but there wasn't a regression test for
this particular bug yet, so this commit adds one.
citrus-it added a commit to citrus-it/ast that referenced this issue Jan 16, 2021
gkamat pushed a commit to gkamat/ast that referenced this issue Apr 28, 2021
Implement a better fix for unsetting special env vars.

See att#7 for more explanations and ksh source code history :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants