This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #128171] Fix assert fail with /@0{0*->@*/*0
authorFather Chrysostomos <sprout@cpan.org>
Wed, 18 May 2016 01:16:52 +0000 (18:16 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 18 May 2016 03:29:11 +0000 (20:29 -0700)
If a syntax error such as * (multiply) followed by an arrow causes the
parser to pop scopes in trying to recover from the error, it might
exit the quote-parsing scope (for parsing the regexp) and point the
lexer’s cursor at the code following the regexp, after the lexer has
noted to itself that it is expected to parse a postfix dereference
(PL_expect==XPOSTDEREF).

The code for parsing a postfix dereference has an assertion which
ends up failing in this case, because the *0 following the regexp,
having sigil that can come after an arrow, goes through the postfix
deref function, which complains about the 0 it did not expect.

If we simply remove the assertion, the lexer will continue to emit
tokens, and we just end up dying (somewhat) gracefully because of the
syntax error, instead of crashing.

I used a ] in the test instead of a final 0, to avoid a compile-
time warning.  (Number found where operator expected.)

t/base/lex.t
toke.c

index 1aa563d..fe46f14 100644 (file)
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..104\n";
+print "1..105\n";
 
 $x = 'x';
 
@@ -522,3 +522,9 @@ eval q|s##[}#e|;
  eval ('qq{@{[0}*sub{]]}}}=sub{0' . "\c[");
  print "ok $test - 125350\n"; $test++;
 }
+
+{
+ # Used to crash [perl #128171]
+ eval ('/@0{0*->@*/*]');
+ print "ok $test - 128171\n"; $test++;
+}
diff --git a/toke.c b/toke.c
index dcde140..4a20e61 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -1932,7 +1932,6 @@ static int
 S_postderef(pTHX_ int const funny, char const next)
 {
     assert(funny == DOLSHARP || strchr("$@%&*", funny));
-    assert(strchr("*[{", next));
     if (next == '*') {
        PL_expect = XOPERATOR;
        if (PL_lex_state == LEX_INTERPNORMAL && !PL_lex_brackets) {