diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-09-06 08:30:41 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-09-06 23:25:49 -0700 |
commit | 8c9d3376fbfa04ec0e0e2164dcf7d9e824cf0e94 (patch) | |
tree | d7a979047d5b68fbfe6d7997270062787f830de6 /pp_ctl.c | |
parent | 425b8234618a94b12ca70c9914e5818c3952c7ed (diff) | |
download | perl-8c9d3376fbfa04ec0e0e2164dcf7d9e824cf0e94.tar.gz |
Stop &xsub and goto &xsub from crashing on undef *_
$ perl -e 'undef *_; &Internals::V'
Segmentation fault: 11
$ perl -e 'sub { undef *_; goto &Internals::V }->()'
$ perl5.18.1 -e 'sub { undef *_; goto &Internals::V }->()'
Segmentation fault: 11
The goto case is actually a regression from 5.16 (049bd5ffd62), as
goto used to ignore changes to *_. (Fixing one bug uncovers another.)
We shouldn’t assume that GvAV(PL_defgv) (*_{ARRAY}) gives us anything.
While we’re at it, since we have to add extra checks anyway, use them
to speed up empty @_ in goto (by checking items, rather than arg).
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -2895,18 +2895,20 @@ PP(pp_goto) /* also pp_dump */ OP* const retop = cx->blk_sub.retop; SV **newsp; I32 gimme; - const SSize_t items = AvFILLp(arg) + 1; + const SSize_t items = arg ? AvFILLp(arg) + 1 : 0; SV** mark; PERL_UNUSED_VAR(newsp); PERL_UNUSED_VAR(gimme); /* put GvAV(defgv) back onto stack */ - EXTEND(SP, items+1); /* @_ could have been extended. */ - Copy(AvARRAY(arg), SP + 1, items, SV*); + if (items) { + EXTEND(SP, items+1); /* @_ could have been extended. */ + Copy(AvARRAY(arg), SP + 1, items, SV*); + } mark = SP; SP += items; - if (AvREAL(arg)) { + if (items && AvREAL(arg)) { I32 index; for (index=0; index<items; index++) if (SP[-index]) |