Skip to content

Commit

Permalink
Localise PL_lex_stuff (crash fix)
Browse files Browse the repository at this point in the history
This fixes crashes and assertion failures related to ticket #123617.

When the lexer encounters a quote-like operator, it scans for the
final delimiter, putting the string in PL_lex_stuff and the replace-
ment, if any, in PL_sublex_info.repl.  Those are just temporary spots
for those values.  As soon as the next token is emitted (FUNC or
PMFUNC), the values are copied to PL_linestr and PL_lex_repl, respec-
tively, after these latter have been localised.

When scan_str (which scans a quote-like op) sees that PL_lex_stuff is
already set, it assumes that it is now parsing a replacement, so it
puts the result in PL_sublex_info.repl.

The FUNC or PMFUNC token for a quote-like operator may trigger a syn-
tax error while PL_lex_stuff and PL_sublex_info.repl are still set.  A
syntax error can cause scopes to be popped, discarding the inner lex-
ing scope (for the quote op) that we were about to enter, but leaving
a PL_lex_stuff value behind.

If another quote-like op is parsed after that, scan_str will assume it
is parsing a replacement since PL_lex_stuff is set.  So you can end up
with a replacement for an op of type OP_MATCH, which is not supposed
to happen.  S_sublex_done fails an assertion in that case.  Some exam-
ples of this bug crash later on non-debugging builds.

Localising PL_lex_stuff fixes the problem.
  • Loading branch information
Father Chrysostomos committed Feb 5, 2015
1 parent 67c71cb commit eabab8b
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
3 changes: 3 additions & 0 deletions t/base/lex.t
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,6 @@ print "ok $test - map{sub :lvalue...}\n"; $test++;
# Used to crash [perl #123711]
0-5x-l{0};
# Used to fail an assertion [perl #123617]
eval '"$a{ 1 m// }"; //';
6 changes: 6 additions & 0 deletions toke.c
Original file line number Diff line number Diff line change
Expand Up @@ -2368,6 +2368,12 @@ S_sublex_push(pTHX)
PL_lex_stuff = NULL;
PL_sublex_info.repl = NULL;

/* Arrange for PL_lex_stuff to be freed on scope exit, in case it gets
set for an inner quote-like operator and then an error causes scope-
popping. We must not have a PL_lex_stuff value left dangling, as
that breaks assumptions elsewhere. See bug #123617. */
SAVEGENERICSV(PL_lex_stuff);

PL_bufend = PL_bufptr = PL_oldbufptr = PL_oldoldbufptr = PL_linestart
= SvPVX(PL_linestr);
PL_bufend += SvCUR(PL_linestr);
Expand Down

0 comments on commit eabab8b

Please sign in to comment.