summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-09-06 08:30:41 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-09-06 23:25:49 -0700
commit8c9d3376fbfa04ec0e0e2164dcf7d9e824cf0e94 (patch)
treed7a979047d5b68fbfe6d7997270062787f830de6 /pp_ctl.c
parent425b8234618a94b12ca70c9914e5818c3952c7ed (diff)
downloadperl-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.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 24a8cd6f05..47d8a1f942 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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])