Skip to content

Commit e47d32d

Browse files
author
Father Chrysostomos
committed
[perl #123712] Fix /$a[/ parsing
The parser used to read more lines of input when parsing code interpo- lated into quote-like operators, under some circumstance. This would result in code like this working, even though it should be a syn- tax error: s||${s/.*/|; /s}Just another Perl hacker, print "${;s/.*/Just an"; other Perl hacker, /s} die or return; print While this was harmless, other cases, like /$a[/<<a with no trailing newline, would cause unexpected internal state that did not meet the reasonable assumptions made by S_scan_heredoc, resulting in a crash. The simplest fix is to modify the function that reads more input, namely, lex_next_chunk, and prevent it from reading more lines of input from inside a quote-like operator. (The alternative would be to modify all the calls to lex_next_chunk, and make them conditional.) That breaks here-doc parsing for things like s//<<EOF/, but the LEX_NO_TERM flag to lex_next_chunk is used only by the here-doc parser, so lex_next_chunk can make an exception if it is set.
1 parent f36b670 commit e47d32d

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

t/op/lex.t

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use warnings;
77

88
BEGIN { chdir 't' if -d 't'; require './test.pl'; }
99

10-
plan(tests => 17);
10+
plan(tests => 18);
1111

1212
{
1313
no warnings 'deprecated';
@@ -151,3 +151,11 @@ gibberish
151151
'gibberish containing &{+z} - used to crash [perl #123753]'
152152
);
153153
}
154+
155+
fresh_perl_is(
156+
'/$a[/<<a',
157+
"syntax error at - line 1, next char ;\n" .
158+
"Can't find string terminator \"a\" anywhere before EOF at - line 1.\n",
159+
{ stderr => 1 },
160+
'/$a[/<<a with no newline [perl #123712]'
161+
);

toke.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ buffer has reached the end of the input text.
12521252
*/
12531253

12541254
#define LEX_FAKE_EOF 0x80000000
1255-
#define LEX_NO_TERM 0x40000000
1255+
#define LEX_NO_TERM 0x40000000 /* here-doc */
12561256

12571257
bool
12581258
Perl_lex_next_chunk(pTHX_ U32 flags)
@@ -1266,6 +1266,8 @@ Perl_lex_next_chunk(pTHX_ U32 flags)
12661266
bool got_some;
12671267
if (flags & ~(LEX_KEEP_PREVIOUS|LEX_FAKE_EOF|LEX_NO_TERM))
12681268
Perl_croak(aTHX_ "Lexing code internal error (%s)", "lex_next_chunk");
1269+
if (!(flags & LEX_NO_TERM) && PL_sublex_info.sub_inwhat)
1270+
return FALSE;
12691271
linestr = PL_parser->linestr;
12701272
buf = SvPVX(linestr);
12711273
if (!(flags & LEX_KEEP_PREVIOUS) &&

0 commit comments

Comments
 (0)