diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-08-22 14:07:44 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-08-22 15:53:27 -0700 |
commit | db4442662555874019f183661252bccd4e4ed138 (patch) | |
tree | 80a3b6de5edef596b5eff49eabd365812269e391 /perl.h | |
parent | 486ffce2e3218c92f8211b19f0be2fc5532f8b57 (diff) | |
download | perl-db4442662555874019f183661252bccd4e4ed138.tar.gz |
[perl #114040] Fix here-docs in multiline re-evals
Commit 5097bf9b8 only partially fixed this, or, rather, did the
groundwork for fixing it.
If we have a pattern like this:
/(?{<<foo . baz
bar
foo
})/
Then PL_linestr contains this while we are parsing the block:
"(?{<<foo . baz\nbar\nfoo\n})"
The code for parsing a here-doc in a multiline PL_linestr buffer
(which applies to here-docs in string evals or in quote-like operat-
ors) likes to modify PL_linestr to contain everything after the
<<heredoc marker except the here-doc body, which has been stolen (but
it oddly includes the last character of the marker, which does not
matter, as PL_bufptr is set to PL_linestart+1):
"o . baz\n})"
The regexp block parsing code expects to be able to extract the entire
block (as a string) from PL_linestr after parsing it. So it is not
helpful for S_scan_heredoc to go and modify it like that.
Before modifying PL_linestr, we can set aside a copy of the source
code (in PL_sublex_info.re_eval_str) from the beginning of the regexp
block to the end of PL_linestr, so that the regexp block code can
retrieve the original source from there.
We also adjust PL_sublex_info.re_eval_start so that at the end of the
regexp block PL_bufptr - PL_sublex_info.re_eval_start is the length of
the block.
Instead of clobbering PL_linestr, we can copy everything after the
here-doc to when the body begins. And this for two reasons: it
requires less allocation (I would have made that change in the end
anyway, for efficiency), and it makes it easier to calculate how much
to subtract from re_eval_start.
This fix does not apply to here-docs in quotes in multiline string
evals, which crashes and always has.
Diffstat (limited to 'perl.h')
-rw-r--r-- | perl.h | 1 |
1 files changed, 1 insertions, 0 deletions
@@ -3458,6 +3458,7 @@ struct _sublex_info { OP *sub_op; /* "lex_op" to use */ char *super_bufptr; /* PL_parser->bufptr that was */ char *re_eval_start;/* start of "(?{..." text */ + SV *re_eval_str; /* "(?{...})" text */ SV *repl; /* replacement of s/// or y/// */ }; |