Don’t let gv.c:gv_try_downgrade touch PL_statgv
authorFather Chrysostomos <sprout@cpan.org>
Sat, 26 Oct 2013 19:28:11 +0000 (12:28 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 26 Oct 2013 19:28:11 +0000 (12:28 -0700)
commitaf230ad61ac7cec0e7f968a5740de6719e1099ec
tree5b673ed9b1050ee1b0348b8d42e8a10237be41aa
parent8cece9139aefc96dd3920fa7908afea1581f51b7
Don’t let gv.c:gv_try_downgrade touch PL_statgv

PL_statgv remembers the handle last used by stat, for the sake of -T _
and -B _.  If a glob is freed when PL_statgv points to it, PL_statgv
is set to null.

gv_try_downgrade exists to remove globs and subs that were (possibly
temporarily) vivified by bareword lookup.  It is called whenever a
gvop is freed and its gv looks like a candidate for downgrading.  That
means it applies, not only to potential sub calls, but also to *foo
and *bar.  gv_try_downgrade may delete a glob from the stash alto-
gether if it is empty.  So eval "*foo if 0" may delete the *foo glob.

If PL_statgv is pointing to *foo, then eval "*foo if 0" may change the
behaviour, which is not supposed to happen:

$ ./perl -Ilib -le 'stat *{"foo"}; -T _; print $!; -T _; print $!'
Bad file descriptor
Bad file descriptor
$ ./perl -Ilib -le 'stat *{"foo"}; -T _; print $!; eval "*foo if 0"; -T _; print $!'
Bad file descriptor
No such file or directory
gv.c
t/op/gv.t