diff options
author | Father Chrysostomos <sprout@cpan.org> | 2015-08-20 09:03:17 +0100 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2015-08-28 20:44:38 +0100 |
commit | feac78b0722d4899f9a306d5fb427fe33e82b9ab (patch) | |
tree | 779d92f5ad28645268a077ad4aa10515230a96e6 | |
parent | 89d3bf64c47772a0c299cec5555c07c208dd1fbf (diff) | |
download | perl-feac78b0722d4899f9a306d5fb427fe33e82b9ab.tar.gz |
[perl #123712] Don’t check sub_inwhat
PL_sublex_info.sub_inwhat (in the parser struct) is a temporary spot
to store the value of PL_lex_inwhat (also in the parser struct)
when a sub-lexing scope (for a quote-like operator) is entered.
PL_lex_inwhat is localised, and the value is copied from its temporary
spot (sub_inwhat) into PL_lex_inwhat.
The PL_sublex_info.sub_inwhat was not localised, but instead the value
was set to 0 when a sub-lexing scope was exited. This value was being
used, in a couple of places, to determine whether we were inside a
quote-like operator. But because the value is not localised, it can
be wrong when it is set to 0, if we have nested lexing scopes.
So this ends up crashing for the same reason described in e47d32dcd5:
echo -n '/$a[m||/<<a' | ./miniperl
perl-5.005_02-1816-g09bef84 added the first use of
PL_sublex_info.sub_inwhat to determine whether we are in a quote-like
operator. (Later it got shifted around.) I copied that in e47d32dcd5
(earlier today), because I assumed the logic was correct. Other parts
of the code use PL_lex_inwhat, which is already localised, as I said,
and does not suffer this problem.
If we do not check PL_sublex_info.sub_inwhat to see if we are in
a quote-like construct, then we don’t need to clear it on lexing
scope exit.
(cherry picked from commit d27f4b916ce5819f564bdd4a135137c457156333)
-rw-r--r-- | t/op/lex.t | 9 | ||||
-rw-r--r-- | toke.c | 5 |
2 files changed, 10 insertions, 4 deletions
diff --git a/t/op/lex.t b/t/op/lex.t index 35d4d9c3de..ac094f8d5f 100644 --- a/t/op/lex.t +++ b/t/op/lex.t @@ -4,7 +4,7 @@ use warnings; BEGIN { chdir 't'; require './test.pl'; } -plan(tests => 9); +plan(tests => 10); { no warnings 'deprecated'; @@ -96,3 +96,10 @@ fresh_perl_is( { stderr => 1 }, '/$a[/<<a with no newline [perl #123712]' ); +fresh_perl_is( + '/$a[m||/<<a', + "syntax error at - line 1, next char ;\n" . + "Execution of - aborted due to compilation errors.\n", + { stderr => 1 }, + '/$a[m||/<<a with no newline [perl #123712]' +); @@ -1315,7 +1315,7 @@ Perl_lex_next_chunk(pTHX_ U32 flags) bool got_some; if (flags & ~(LEX_KEEP_PREVIOUS|LEX_FAKE_EOF|LEX_NO_TERM)) Perl_croak(aTHX_ "Lexing code internal error (%s)", "lex_next_chunk"); - if (!(flags & LEX_NO_TERM) && PL_sublex_info.sub_inwhat) + if (!(flags & LEX_NO_TERM) && PL_lex_inwhat) return FALSE; linestr = PL_parser->linestr; buf = SvPVX(linestr); @@ -1962,7 +1962,7 @@ S_skipspace_flags(pTHX_ char *s, U32 flags) STRLEN bufptr_pos = PL_bufptr - SvPVX(PL_linestr); PL_bufptr = s; lex_read_space(flags | LEX_KEEP_PREVIOUS | - (PL_sublex_info.sub_inwhat || PL_lex_state == LEX_FORMLINE ? + (PL_lex_inwhat || PL_lex_state == LEX_FORMLINE ? LEX_NO_NEXT_CHUNK : 0)); s = PL_bufptr; PL_bufptr = SvPVX(PL_linestr) + bufptr_pos; @@ -2797,7 +2797,6 @@ S_sublex_done(pTHX) PL_bufend = SvPVX(PL_linestr); PL_bufend += SvCUR(PL_linestr); PL_expect = XOPERATOR; - PL_sublex_info.sub_inwhat = 0; return ')'; } } |