mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix LINENO after unsetting it a virtual subshell (#283)
There is a TODO note in variables.sh that notes the value of LINENO
is wrong after a virtual subshell. The following script should
print '6', but the bug causes it to print '1' instead:
$ cat /tmp/lineno
#!/bin/ksh
(
unset LINENO
:
)
echo $LINENO
This bug started to occur after the bugfix applied in 7b994b6a.
However, that commit is not where the cause of bug was (when that
bugfix is applied to ksh versions 2008-07-25 through 2012-01-01,
$LINENO works fine). Rather, the cause of this bug was introduced
in 93u+ 2012-02-29. In that version, the mp->nvfun pointer was only
copied from np->nvfun if the variable can be freed from memory.
This is what caused 7b994b6a to break $LINENO in subshells, so to
fix this bug the mp->nvfun and np->nvfun must point to the same
object, even when the variable isn't freed from memory.
src/cmd/ksh93/sh/subshell.c: nv_restore():
- Always copy the np->nvfun pointer to mp->nvfun. To prevent
crashes, the value of np->nvfun->nofree is set to the value given
by the nofree variable, which is set before _nv_unset. See also
commit 7e7f1372, which fixed a crash that happened because
_nv_unset discards the NV_NOFREE flag.
src/cmd/ksh93/tests/variables.sh:
- Remove the workaround for LINENO after a virtual subshell.
- Add a regression test for the value of LINENO when unset in a
virtual subshell, then used after the subshell. Note that before
commit 997ad43b LINENO's value was corrupted after being unset in
a subshell, so the test checks for corruption of the LINENO
variable (in prior commits LINENO was set to '49' because of the
previous bug).
This commit is contained in:
parent
01c01fe8f6
commit
2c22ace1e6
3 changed files with 19 additions and 3 deletions
3
NEWS
3
NEWS
|
|
@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
||||||
- shcomp (the shell bytecode compiler) was fixed to correctly compile process
|
- shcomp (the shell bytecode compiler) was fixed to correctly compile process
|
||||||
substitutions used as the file name to a redirection, as in 'cmd < <(cmd)'.
|
substitutions used as the file name to a redirection, as in 'cmd < <(cmd)'.
|
||||||
|
|
||||||
|
- Fixed a bug introduced on 2020-07-13 that set LINENO to the wrong line
|
||||||
|
number after leaving a virtual subshell in which LINENO had been unset.
|
||||||
|
|
||||||
2021-04-21:
|
2021-04-21:
|
||||||
|
|
||||||
- Fixed a bug introduced on 2020-09-28 that caused an interactive ksh to exit
|
- Fixed a bug introduced on 2020-09-28 that caused an interactive ksh to exit
|
||||||
|
|
|
||||||
|
|
@ -381,8 +381,9 @@ static void nv_restore(struct subshell *sp)
|
||||||
nv_setsize(mp,nv_size(np));
|
nv_setsize(mp,nv_size(np));
|
||||||
if(!(flags&NV_MINIMAL))
|
if(!(flags&NV_MINIMAL))
|
||||||
mp->nvenv = np->nvenv;
|
mp->nvenv = np->nvenv;
|
||||||
if(!nofree)
|
|
||||||
mp->nvfun = np->nvfun;
|
mp->nvfun = np->nvfun;
|
||||||
|
if(np->nvfun && nofree)
|
||||||
|
np->nvfun->nofree = nofree;
|
||||||
if(nv_isattr(np,NV_IDENT))
|
if(nv_isattr(np,NV_IDENT))
|
||||||
{
|
{
|
||||||
nv_offattr(np,NV_IDENT);
|
nv_offattr(np,NV_IDENT);
|
||||||
|
|
|
||||||
|
|
@ -720,7 +720,6 @@ set --
|
||||||
|
|
||||||
unset r v x
|
unset r v x
|
||||||
(
|
(
|
||||||
ulimit -t unlimited 2>/dev/null # TODO: this test messes up LINENO past the subshell unless we fork it
|
|
||||||
x=foo
|
x=foo
|
||||||
for v in EDITOR VISUAL OPTIND CDPATH FPATH PATH ENV RANDOM SECONDS _ LINENO
|
for v in EDITOR VISUAL OPTIND CDPATH FPATH PATH ENV RANDOM SECONDS _ LINENO
|
||||||
do nameref r=$v
|
do nameref r=$v
|
||||||
|
|
@ -1272,5 +1271,18 @@ if ((nsec<osec || nsec>osec+0.1))
|
||||||
then err_exit "SECONDS corrupted after leaving virtual subshell (expected $osec, got $nsec)"
|
then err_exit "SECONDS corrupted after leaving virtual subshell (expected $osec, got $nsec)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Corruption of LINENO on leaving virtual subshell
|
||||||
|
lineno_subshell=$tmp/lineno_subshell.sh
|
||||||
|
cat >| "$lineno_subshell" << 'EOF'
|
||||||
|
(
|
||||||
|
unset LINENO
|
||||||
|
:
|
||||||
|
)
|
||||||
|
echo $LINENO
|
||||||
|
EOF
|
||||||
|
exp=5
|
||||||
|
got=$($SHELL "$lineno_subshell")
|
||||||
|
[[ $exp == $got ]] || err_exit "LINENO corrupted after leaving virtual subshell (expected $exp, got $got)"
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue