diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-10-26 12:28:11 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-10-26 12:28:11 -0700 |
commit | af230ad61ac7cec0e7f968a5740de6719e1099ec (patch) | |
tree | 5b673ed9b1050ee1b0348b8d42e8a10237be41aa /gv.c | |
parent | 8cece9139aefc96dd3920fa7908afea1581f51b7 (diff) | |
download | perl-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.c | 1 |
1 files changed, 1 insertions, 0 deletions
@@ -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 */ |