1
0
Fork 0
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:
Johnothan King 2021-04-22 11:16:25 -07:00 committed by GitHub
parent 01c01fe8f6
commit 2c22ace1e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 3 deletions

3
NEWS
View file

@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
- shcomp (the shell bytecode compiler) was fixed to correctly compile process
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:
- Fixed a bug introduced on 2020-09-28 that caused an interactive ksh to exit

View file

@ -381,8 +381,9 @@ static void nv_restore(struct subshell *sp)
nv_setsize(mp,nv_size(np));
if(!(flags&NV_MINIMAL))
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))
{
nv_offattr(np,NV_IDENT);

View file

@ -720,7 +720,6 @@ set --
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
for v in EDITOR VISUAL OPTIND CDPATH FPATH PATH ENV RANDOM SECONDS _ LINENO
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)"
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))