Skip to content

Commit c304acb

Browse files
committed
pp_ctl.c - use try_yyparse() for eval
CATCH_GET is never true in this code, so we never called try_yyparse() which in turn meant we leaked debug data from failed evals. With this in place an eval that dies during compile will always be handled by doeval_comp() properly. This includes changes to t/comp/readlines.t so it tests code that croaks during compile, which used to leak and fail test but was not actually tested. This fixes GH Issue #20161.
1 parent aeff225 commit c304acb

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

pp_ctl.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3686,12 +3686,13 @@ S_doeval_compile(pTHX_ U8 gimme, CV* outside, U32 seq, HV *hh)
36863686

36873687
CALL_BLOCK_HOOKS(bhk_eval, saveop);
36883688

3689-
/* note that yyparse() may raise an exception, e.g. C<BEGIN{die}>,
3690-
* so honour CATCH_GET and trap it here if necessary */
3691-
3692-
3689+
/* we should never be CATCH_GET true here, as our immediate callers should
3690+
* always handle that case. */
3691+
assert(!CATCH_GET);
36933692
/* compile the code */
3694-
yystatus = (!in_require && CATCH_GET) ? S_try_yyparse(aTHX_ GRAMPROG) : yyparse(GRAMPROG);
3693+
yystatus = (!in_require)
3694+
? S_try_yyparse(aTHX_ GRAMPROG)
3695+
: yyparse(GRAMPROG);
36953696

36963697
if (yystatus || PL_parser->error_count || !PL_eval_root) {
36973698
PERL_CONTEXT *cx;
@@ -4578,6 +4579,8 @@ PP(pp_entereval)
45784579
if (CATCH_GET)
45794580
return docatch(Perl_pp_entereval);
45804581

4582+
assert(!CATCH_GET);
4583+
45814584
gimme = GIMME_V;
45824585
was = PL_breakable_sub_gen;
45834586
saved_delete = FALSE;

t/comp/retainedlines.t

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# we've not yet verified that use works.
77
# use strict;
88

9-
print "1..75\n";
9+
print "1..98\n";
1010
my $test = 0;
1111

1212
sub failed {
@@ -101,7 +101,10 @@ for my $sep (' ', "\0") {
101101
my $prog = "sub $name {
102102
'This is $name'
103103
}
104-
1 +
104+
# 10 errors to triger a croak during compilation.
105+
1 +; 1 +; 1 +; 1 +; 1 +;
106+
1 +; 1 +; 1 +; 1 +; 1 +;
107+
1 +; # and one more for good measure.
105108
";
106109

107110
eval $prog and die;
@@ -119,7 +122,9 @@ foreach my $flags (0x0, 0x800, 0x1000, 0x1800) {
119122
# This is easier if we accept that the guts eval will add a trailing \n
120123
# for us
121124
my $prog = "1 + 1 + 1\n";
122-
my $fail = "1 + \n";
125+
my $fail = "1 +;\n" x 11; # we need 10 errors to trigger a croak during
126+
# compile, we add an extra one just for good
127+
# measure.
123128

124129
is (eval $prog, 3, 'String eval works');
125130
if ($flags & 0x800) {

0 commit comments

Comments
 (0)