This works fine:
eval ' s//<<END.""/e; print
Just another Perl hacker,
END
'or die $@
__END__
Just another Perl hacker,
But this doesn’t:
eval ' s//"$1".<<END/e; print
Just another Perl hacker,
END
'or die $@
__END__
Can't find string terminator "END" anywhere before EOF at (eval 1) line 1.
It fails because PL_sublex_info.super_buf*, added by commit
0244c3a403, are not localised, so, after the "", s/// sees its own
buffer pointers in those variables, instead of its parent string eval.
This used to happen only with s///e inside s///e, but that was because
here-docs would peek inside the parent linestr buffer only inside
s///e, and not other quote-like operators. That was fixed in
recent commits.
Simply moving the assignment of super_buf* into sublex_push does solve
the bug for a simple "", as "" does sublex_start, but not sublex_push.
We do need to localise those variables for "${\''}", however.
#!./perl
-print "1..57\n";
+print "1..58\n";
$x = 'x';
@a = (1,2,3);
print "not " unless($a[~~2] == 3);
print "ok 57\n";
+
+$_ = "";
+eval 's/(?:)/"${\q||}".<<\END/e;
+ok 58 - heredoc after "" in s/// in eval
+END
+';
+print $_ || "not ok 58\n";
dVAR;
const I32 op_type = pl_yylval.ival;
- PL_sublex_info.super_bufptr = PL_bufptr;
- PL_sublex_info.super_bufend = PL_bufend;
if (op_type == OP_NULL) {
pl_yylval.opval = PL_lex_op;
PL_lex_op = NULL;
SAVEI32(PL_lex_starts);
SAVEI8(PL_lex_state);
SAVEPPTR(PL_sublex_info.re_eval_start);
+ SAVEPPTR(PL_sublex_info.super_bufptr);
+ SAVEPPTR(PL_sublex_info.super_bufend);
SAVEVPTR(PL_lex_inpat);
SAVEI16(PL_lex_inwhat);
SAVECOPLINE(PL_curcop);
PL_linestr = PL_lex_stuff;
PL_lex_stuff = NULL;
PL_sublex_info.re_eval_start = NULL;
+ PL_sublex_info.super_bufptr = PL_bufptr;
+ PL_sublex_info.super_bufend = PL_bufend;
PL_bufend = PL_bufptr = PL_oldbufptr = PL_oldoldbufptr = PL_linestart
= SvPVX(PL_linestr);