diff options
author | Father Chrysostomos <sprout@cpan.org> | 2015-02-22 14:34:42 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2015-02-22 16:37:20 -0800 |
commit | f4460c6f7a0de152ddaed69a0ba0efe653258f81 (patch) | |
tree | 8d7c596faa0a889a998c07da121724e76699ee59 /t/base | |
parent | a2867f88735d49c5b668c01984acdb846d8b2e71 (diff) | |
download | perl-f4460c6f7a0de152ddaed69a0ba0efe653258f81.tar.gz |
[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.
Diffstat (limited to 't/base')
-rw-r--r-- | t/base/lex.t | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/t/base/lex.t b/t/base/lex.t index 5449b46c7c..47816fc13d 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|; |