1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Better fix for BUG_IFSISSET (re: 95294419)

With a better understanding of the code 1.5 years later, the
special-casing for IFS introduced in that commit seems like a hack.

The problem was not that the IFS node always exists but that it is
always considered to have a 'get' discipline function. Variables
with a 'get' discipline are considered set. This makes sense for
all variables except IFS.

The nv_isnull() macro is used to check if a variable is set. It
calls nv_hasget() to determine if the variable has a 'get'
discipline. So a better fix is for nv_hasget() always to return
false for IFS.

src/cmd/ksh93/bltins/test.c, src/cmd/ksh93/sh/macro.c:
- Remove special-casing for IFS.

src/cmd/ksh93/sh/nvdisc.c: nv_hasget():
- Always return false for IFS, taking local scope into account.
This commit is contained in:
Martijn Dekker 2021-11-13 00:49:01 +01:00
parent 69e0de9274
commit a381a1b049
3 changed files with 7 additions and 8 deletions

View file

@ -490,8 +490,6 @@ int test_unop(Shell_t *shp,register int op,register const char *arg)
}
if(ap = nv_arrayptr(np))
return(nv_arrayisset(np,ap));
if(*arg=='I' && strcmp(arg,"IFS")==0)
return(nv_getval(np)!=NULL); /* avoid BUG_IFSISSET */
return(!nv_isnull(np));
}
default:

View file

@ -1318,13 +1318,8 @@ retry1:
flag &= ~NV_NOADD;
/*
* Get a node pointer (np) to the parameter, if any.
*
* The IFS node always exists, so we must special-case IFS by checking if it has
* a value; otherwise it always follows the code path for a set parameter, so is
* not subject to 'set -u', and may test as set even after 'unset -v IFS'.
*/
if(!(*id=='I' && strcmp(id,"IFS")==0 && nv_getval(sh_scoped(mp->shp,IFSNOD)) == NIL(char*)))
np = nv_open(id,mp->shp->var_tree,flag|NV_NOFAIL);
np = nv_open(id,mp->shp->var_tree,flag|NV_NOFAIL);
if(!np)
{
sfprintf(mp->shp->strbuf,"%s%c",id,0);

View file

@ -1497,9 +1497,15 @@ const Namdisc_t *nv_discfun(int which)
return(0);
}
/*
* Check if a variable node has a 'get' discipline.
* Used by the nv_isnull() macro (see include/name.h).
*/
int nv_hasget(Namval_t *np)
{
register Namfun_t *fp;
if(np==sh_scoped(&sh,IFSNOD))
return(0); /* avoid BUG_IFSISSET: always return false for IFS */
for(fp=np->nvfun; fp; fp=fp->next)
{
if(!fp->disc || (!fp->disc->getnum && !fp->disc->getval))