Skip to content

Commit 1d59c03

Browse files
author
Father Chrysostomos
committed
[perl #99850] SEGV when destructor undefs goto &sub
If goto &sub triggers a destructor that undefines &sub, a crash ensues. This commit adds an extra check in pp_goto after the unwinding of the previous sub’s scope.
1 parent 6cf9034 commit 1d59c03

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

pp_ctl.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2879,6 +2879,19 @@ PP(pp_goto)
28792879
oldsave = PL_scopestack[PL_scopestack_ix - 1];
28802880
LEAVE_SCOPE(oldsave);
28812881

2882+
/* A destructor called during LEAVE_SCOPE could have undefined
2883+
* our precious cv. See bug #99850. */
2884+
if (!CvROOT(cv) && !CvXSUB(cv)) {
2885+
const GV * const gv = CvGV(cv);
2886+
if (gv) {
2887+
SV * const tmpstr = sv_newmortal();
2888+
gv_efullname3(tmpstr, gv, NULL);
2889+
DIE(aTHX_ "Goto undefined subroutine &%"SVf"",
2890+
SVfARG(tmpstr));
2891+
}
2892+
DIE(aTHX_ "Goto undefined subroutine");
2893+
}
2894+
28822895
/* Now do some callish stuff. */
28832896
SAVETMPS;
28842897
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */

t/op/goto.t

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ BEGIN {
1010

1111
use warnings;
1212
use strict;
13-
plan tests => 78;
13+
plan tests => 79;
1414
our $TODO;
1515

1616
my $deprecated = 0;
@@ -205,6 +205,17 @@ sub f1 {
205205
}
206206
f1();
207207

208+
# bug #99850, which is similar - freeing the subroutine we are about to
209+
# go(in)to during a FREETMPS call should not crash perl.
210+
211+
package _99850 {
212+
sub reftype{}
213+
DESTROY { undef &reftype }
214+
eval { sub { my $guard = bless []; goto &reftype }->() };
215+
}
216+
like $@, qr/^Goto undefined subroutine &_99850::reftype at /,
217+
'goto &foo undefining &foo on sub cleanup';
218+
208219
# bug #22181 - this used to coredump or make $x undefined, due to
209220
# erroneous popping of the inner BLOCK context
210221

0 commit comments

Comments
 (0)