summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-10-26 12:28:11 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-10-26 12:28:11 -0700
commitaf230ad61ac7cec0e7f968a5740de6719e1099ec (patch)
tree5b673ed9b1050ee1b0348b8d42e8a10237be41aa /gv.c
parent8cece9139aefc96dd3920fa7908afea1581f51b7 (diff)
downloadperl-af230ad61ac7cec0e7f968a5740de6719e1099ec.tar.gz
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
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/gv.c b/gv.c
index 476afc547c..4e0611b66b 100644
--- a/gv.c
+++ b/gv.c
@@ -3322,6 +3322,7 @@ Perl_gv_try_downgrade(pTHX_ GV *gv)
!GvSV(gv) && !GvAV(gv) && !GvHV(gv) && !GvIOp(gv) && !GvFORM(gv) &&
GvEGVx(gv) == gv && (stash = GvSTASH(gv))))
return;
+ if (gv == PL_statgv) return;
if (SvMAGICAL(gv)) {
MAGIC *mg;
/* only backref magic is allowed */