This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #123452] Fix crash with s/${<>{})//
s/foo/bar/ tokenizes as something akin to subst("foo","bar") and the
resulting list op representing the contents of the parentheses is
passed to pmruntime as its expr argument.
If we have invalid code like s/${<>{})//, the bison parser will dis-
card invalid tokens until it finds something it can fall back to, in
an attempt to keep parsing (to report as many errors as possible).
In the process of discarding tokens, it may convert s/${<>{})//, which
the lexer emits like this:
PMFUNC ( $ { THING(readline) { } ) , "" )
into this:
PMFUNC ( $ { THING(readline) } ) , "" )
(or something similar). So when the parser sees the first closing
parentheses, it decides it has a complete PMFUNC(...), and the expr
argument to pmruntime ends up being an rv2sv op (the ${...}), not
a list op.
pmruntime assumes it is a list op, and tries to access its op_last
field, to find the replacement part; but rv2sv has no op_last field,
so this reads past the end of the op struct, usually into the first
pointer in the next op slot, which itself is an opslot pointer, not an
op pointer, so things really screw up.
If we check that the arguments to subst are indeed a list op first
before trying to extract the replacement part, everything works. We
get the syntax errors reported as expected, but no crash.