mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
nv_setlist(): add check for readonly (re: 264ba48b
)
One area where readonly is still ineffective is the local environment list for a command (preceding assignments) if that command is not executed using exec(3) after fork(2). Builtin commands are one example. The following succeeds but should fail: (readonly v=1; v=2 true) # succeeds, but should fail If the shell is compiled with SHOPT_SPAWN (the default) then this also applies to external commands invoked with sh_ntfork(): (readonly v=1; v=2 env) # succeeds if SHOPT_SPAWN This presents to the user as inconsitent behaviour because external commands may be fork()ed under certain circumstances but not others, depending on complex optimisations. One example is: $ ksh -c 'readonly v=1; v=2 env' ksh: v: is read only $ ksh -c 'readonly v=1; v=2 env; :' (bad: environment list is output, including 'v=2') In the first command above, where 'v2=env' is the last command in the -c script, the optimisation skips creating a scope and assigns the environment list in the current scope. src/cmd/ksh93/sh/name.c: nv_setlist(): - Add check for readonly. This requires searching for the variable in the main tree using nv_search() before a locally scoped one is added using nv_open(). Since nv_search() only works with plain variable names, temporarily end the string at '='. src/cmd/ksh93/tests/readonly.sh: - Add version check and fork the test command substitution subshell on older versions that would otherwise abort the tests due to the combination of an excessively low arithmetic recursion tolerance and a bug that sometimes fails to restore the shell's arithmetic recursion level.
This commit is contained in:
parent
66c37202fd
commit
f6bc5c03ca
2 changed files with 19 additions and 0 deletions
|
@ -261,6 +261,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
|
|||
Shell_t *shp = sh_getinterp();
|
||||
register char *cp;
|
||||
register Namval_t *np, *mp;
|
||||
char *eqp;
|
||||
char *trap=shp->st.trap[SH_DEBUGTRAP];
|
||||
char *prefix = shp->prefix;
|
||||
int traceon = (sh_isoption(SH_XTRACE)!=0);
|
||||
|
@ -592,6 +593,19 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
|
|||
cp = arg->argval;
|
||||
mp = 0;
|
||||
}
|
||||
if(eqp = strchr(cp,'='))
|
||||
{
|
||||
/* Check for read-only */
|
||||
*eqp = '\0';
|
||||
np = nv_search(cp,shp->var_tree,0);
|
||||
*eqp = '=';
|
||||
if(np && nv_isattr(np,NV_RDONLY))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_readonly,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
}
|
||||
np = nv_open(cp,shp->prefix_root?shp->prefix_root:shp->var_tree,flags);
|
||||
if(!np->nvfun && (flags&NV_NOREF))
|
||||
{
|
||||
|
|
|
@ -319,6 +319,7 @@ n=${#rtests[@]}
|
|||
for ((i=0; i<$n; i++))
|
||||
do
|
||||
got=$(
|
||||
((.sh.version < 20210404)) && ulimit -t unlimited 2>/dev/null # fork to dodge an arith recursion detection bug
|
||||
trap "${rtests[$i].res}" EXIT
|
||||
eval "${rtests[$i].ini}"
|
||||
eval "${rtests[$i].chg}" 2>&1
|
||||
|
@ -340,5 +341,9 @@ unset i n got rtests
|
|||
(readonly v=1; typeset -x v) 2>/dev/null || err_exit "readonly variable cannot be exported (2)"
|
||||
(readonly v=1; typeset -rx v) 2>/dev/null || err_exit "readonly variable cannot be set readonly and exported"
|
||||
|
||||
# ======
|
||||
# the environment list was not checked for readonly for commands that are not fork()ed
|
||||
(readonly v=1; v=2 true) 2>/dev/null && err_exit 'readonly not verified for command environment list'
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue