summaryrefslogtreecommitdiff
path: root/t/op/goto.t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2018-02-04 22:50:15 -0800
committerFather Chrysostomos <sprout@cpan.org>2018-02-04 22:51:36 -0800
commit4bfb5532d393d56b18d13bc19f70f6f7a64ae781 (patch)
tree5f996c3570fed22d54b35d6fb9792c94a112a626 /t/op/goto.t
parentae315a0a3c51e68887704d4907bb6a502a6d4e3f (diff)
downloadperl-4bfb5532d393d56b18d13bc19f70f6f7a64ae781.tar.gz
[perl #132799] Fix goto within block within expr
When goto looks for a label, it builds up a list of ops to enter. But it begins its search a little too far out relative to the ‘goto’. Hence, the first op gets skipped. In 6d90e983841, I forbade same cases of inward goto-into-expression to avoid stack corruption and crashes. I did this by pushing a marker on to the list of ops to enter, indicating that an error should be thrown instead. Because goto starts the search too far up the context stack, it would sometimes end up looking inside an expression, which would cause the first op on the entry list to be such a marker, meaning that the next item, which should have been skipped, would not be. That could really screw up the context stack for cases like: my $e = eval { goto label; label: } because the entry list would be: <croak-marker> entertry instead of the previous: entertry Hence, entertry (which enters eval{}) would be executed from *within* the eval, causing the exit of the eval to leave an eval on the context stack. Crashes ensued. This commit fixes it by checking whether we have moved past the begin- ning of the list of entry ops before pushing a croak-marker on to it. Goto’s implementation is really complex, and always has been. It could be greatly simplified now thot ops have parent pointers. But that should wait for another developement cycle.
Diffstat (limited to 't/op/goto.t')
-rw-r--r--t/op/goto.t14
1 files changed, 13 insertions, 1 deletions
diff --git a/t/op/goto.t b/t/op/goto.t
index 9b7e5ec2f7..2bd7972945 100644
--- a/t/op/goto.t
+++ b/t/op/goto.t
@@ -10,7 +10,7 @@ BEGIN {
use warnings;
use strict;
-plan tests => 121;
+plan tests => 122;
our $TODO;
my $deprecated = 0;
@@ -858,3 +858,15 @@ is sub { goto z; exit do { z: return "foo" } }->(), 'foo',
'goto into exit';
is sub { goto z; eval do { z: "'foo'" } }->(), 'foo',
'goto into eval';
+
+# [perl #132799]
+# Erroneous inward goto warning, followed by crash.
+# The eval must be in an assignment.
+sub _routine {
+ my $e = eval {
+ goto L2;
+ L2:
+ }
+}
+_routine();
+pass("bug 132799");