diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-01-18 19:16:55 -0800 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2014-04-16 11:20:29 +1000 |
commit | 2c60386e935e57af3d9202ad4b798662d2e997a1 (patch) | |
tree | 73ed27ce9df3179a98d2beadf70e3b46ad81dca9 | |
parent | 1d88b12bc04aeae558bc19c4b08b7e682bbdd598 (diff) | |
download | perl-2c60386e935e57af3d9202ad4b798662d2e997a1.tar.gz |
[perl #119949] Stop undef *_, goto &sub from crashing
Commit 049bd5ffd62b fixed problems with the wrong @_ being visible
after *_ modification followed by goto. In so doing, it made it
possible for a null to be placed at the start of the target sub’s
pad, because it was not checking that the array it got from PL_defgv
was actually non-null. Simply adding the check makes everything work.
Conflicts:
t/op/goto.t
-rw-r--r-- | pp_ctl.c | 6 | ||||
-rw-r--r-- | t/op/goto.t | 19 |
2 files changed, 22 insertions, 3 deletions
@@ -2956,8 +2956,10 @@ PP(pp_goto) to freed memory as the result of undef *_. So put it in the callee’s pad, donating our refer- ence count. */ - SvREFCNT_dec(PAD_SVl(0)); - PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg); + if (arg) { + SvREFCNT_dec(PAD_SVl(0)); + PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg); + } /* GvAV(PL_defgv) might have been modified on scope exit, so restore it. */ diff --git a/t/op/goto.t b/t/op/goto.t index 37b69e38df..a2d9df85aa 100644 --- a/t/op/goto.t +++ b/t/op/goto.t @@ -10,7 +10,7 @@ BEGIN { use warnings; use strict; -plan tests => 89; +plan tests => 91; our $TODO; my $deprecated = 0; @@ -482,6 +482,23 @@ sub { *__ = \@_; goto &null } -> ("rough and tubbery"); is ${*__}[0], 'rough and tubbery', 'goto &foo leaves reified @_ alone'; +# goto &perlsub when @_ itself does not exist [perl #119949] +# This was only crashing when the replaced sub call had an argument list. +# (I.e., &{ sub { goto ... } } did not crash.) +sub { + undef *_; + goto sub { + is *_{ARRAY}, undef, 'goto &perlsub when @_ does not exist'; + } +}->(); +sub { + local *_; + goto sub { + is *_{ARRAY}, undef, 'goto &sub when @_ does not exist (local *_)'; + } +}->(); + + # [perl #36521] goto &foo in warn handler could defeat recursion avoider { |