diff options
author | Father Chrysostomos <sprout@cpan.org> | 2018-02-04 22:50:15 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2018-02-04 22:51:36 -0800 |
commit | 4bfb5532d393d56b18d13bc19f70f6f7a64ae781 (patch) | |
tree | 5f996c3570fed22d54b35d6fb9792c94a112a626 /t/op/goto.t | |
parent | ae315a0a3c51e68887704d4907bb6a502a6d4e3f (diff) | |
download | perl-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.t | 14 |
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"); |