mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix typeset attributes -a, -A, -l, -u leaking out of subshells
If an array or upper/lowercase variable was declared with a null initial value within a virtual/non-forked subshell, like: ( typeset -a foo; ... ) ( typeset -A foo; ... ) ( typeset -l foo; ... ) ( typeset -u foo; ... ) then the type declaration leaked out of the subshell into the parent shell environment, though without any values that may subsequently have been assigned. src/cmd/ksh93/bltins/typeset.c: setall(): - When deciding whether to create a virtual subshell scope for a variable, use sh_assignok(), which was actually designed for the purpose, instead of _nv_unset(). This allows getting rid of a tangled mess of special-casing that never worked quite right. src/cmd/ksh93/tests/arrays.sh: - Add regression tests checking that array declarations don't leak out of virtual subshells. src/cmd/ksh93/tests/attributes.sh: - Add regression tests for combining the 'export' and 'readonly' attributes with every other possible typeset attribute on unset variables. This also includes a subshell leak test for each one. Fixes: https://github.com/ksh93/ksh/issues/88
This commit is contained in:
parent
1bc2c74c74
commit
a2f13c19f2
4 changed files with 99 additions and 5 deletions
|
@ -691,13 +691,22 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
|
|||
if(!comvar && !iarray)
|
||||
continue;
|
||||
}
|
||||
if(!nv_isarray(np) && !strchr(name,'=') && !(shp->envlist && nv_onlist(shp->envlist,name)))
|
||||
|
||||
/* Create local scope for virtual subshell */
|
||||
if(shp->subshell)
|
||||
{
|
||||
if(comvar || (shp->last_root==shp->var_tree && (tp->tp || (!shp->st.real_fun && (nvflags&NV_STATIC)) || (!(flag&(NV_EXPORT|NV_RDONLY)) && nv_isattr(np,(NV_EXPORT|NV_IMPORT))==(NV_EXPORT|NV_IMPORT)))))
|
||||
{
|
||||
_nv_unset(np,0);
|
||||
}
|
||||
if(!nv_isattr(np,NV_NODISC|NV_ARRAY) && !nv_isvtree(np))
|
||||
{
|
||||
/*
|
||||
* 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,2);
|
||||
}
|
||||
else
|
||||
np=sh_assignok(np,0);
|
||||
}
|
||||
|
||||
if(troot==shp->var_tree)
|
||||
{
|
||||
if(iarray)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue