In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/f4460c6f7a0de152ddaed69a0ba0efe653258f81?hp=f266b7436d2272bf0b223187f6f07c5a7e18834c>

- Log -----------------------------------------------------------------
commit f4460c6f7a0de152ddaed69a0ba0efe653258f81
Author: Father Chrysostomos <[email protected]>
Date:   Sun Feb 22 14:34:42 2015 -0800

    [perl #123801] Stop s##[}#e from crashing
    
    The lexer normally turns s##...#e into
    
    PMFUNC '(' WORD '/' DO '{' ... ';' '}' ')'
    
    If you have [} inside the replacement, that becomes '[' ';' '}'.  When
    the parser gets to the second semicolon, it pops scopes to try to
    recover from the syntax error, and in so doing it exits the inner lex-
    ing scope that was set up for the substitution.
    
    When that happens, the second '}' is already on the pending token
    stack.  Since we set the lexing state to LEX_KNOWNEXT when there is a
    pending token (though we may not have to; see 7aa8cb0dec1), we have to
    record a pending state as well, so we know what to set the state back
    to.  That pending state is not localised, and, in this case, was set
    before the scopes were popped.
    
    So we end up in the outermost lexing scope, with the lexing state set
    to LEX_INTERPEND.
    
    Inside an inner lexing scope, PL_linestr is of type PVIV, with the IVX
    field used to hold extra information about the type of quote.  In the
    main lexing scope, PL_linestr is an SVt_PV with no IVX field.
    
    If the lexing state is LEX_INTERPanything, it is assumed that
    PL_linestr has an IVX field, which is not the case here, so we fail an
    assertion or crash.
    
    The safest pre-5.22 solution is to check the type of PL_linestr before
    reading IVX.

M       t/base/lex.t
M       toke.c

commit a2867f88735d49c5b668c01984acdb846d8b2e71
Author: Father Chrysostomos <[email protected]>
Date:   Sun Feb 22 11:26:15 2015 -0800

    parser.h: Make nexttoke unsigned
    
    This is to avoid a compiler warning at toke.c:1912 (the assertion in
    S_force_next).  The only values this member can contain are 0 to 5, so
    this change is safe.  (I’ll probably change it to U8 after 5.22.)

M       parser.h
-----------------------------------------------------------------------

Summary of changes:
 parser.h     | 2 +-
 t/base/lex.t | 3 +++
 toke.c       | 8 ++++++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/parser.h b/parser.h
index 2806578..ffc60d3 100644
--- a/parser.h
+++ b/parser.h
@@ -100,7 +100,7 @@ typedef struct yy_parser {
 
     YYSTYPE    nextval[5];     /* value of next token, if any */
     I32                nexttype[5];    /* type of next token */
-    I32                nexttoke;
+    U32                nexttoke;
 
     COP                *saved_curcop;  /* the previous PL_curcop */
     char       tokenbuf[256];
diff --git a/t/base/lex.t b/t/base/lex.t
index 5449b46..47816fc 100644
--- a/t/base/lex.t
+++ b/t/base/lex.t
@@ -494,3 +494,6 @@ eval '"$a{ 1 m// }"; //';
  local $SIG{__WARN__}=sub{};
  eval q|s)$0{0h());qx(@0);qx(@0);qx(@0)|;
 }
+
+# Used to crash [perl #123801]
+eval q|s##[}#e|;
diff --git a/toke.c b/toke.c
index 4910b6b..db511c5 100644
--- a/toke.c
+++ b/toke.c
@@ -4547,6 +4547,14 @@ Perl_yylex(pTHX)
        if (PL_bufptr == PL_bufend)
            return REPORT(sublex_done());
 
+       /* Treat state as LEX_NORMAL if SvIVX is not valid on PL_linestr.
+          XXX This hack can be removed if we stop setting PL_lex_state to
+          LEX_KNOWNEXT.  */
+       if (SvTYPE(PL_linestr) == SVt_PV) {
+           PL_lex_state = LEX_NORMAL;
+           break;
+       }
+
        /* m'foo' still needs to be parsed for possible (?{...}) */
        if (SvIVX(PL_linestr) == '\'' && !PL_lex_inpat) {
            SV *sv = newSVsv(PL_linestr);

--
Perl5 Master Repository

Reply via email to