This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
lex_grow_linestr(): update re_eval_start
authorDavid Mitchell <davem@iabyn.com>
Tue, 24 Jul 2012 14:11:29 +0000 (15:11 +0100)
committerDavid Mitchell <davem@iabyn.com>
Tue, 24 Jul 2012 14:17:42 +0000 (15:17 +0100)
As seen in [perl #114242], the TryCatch test suite triggers this bug.
lex_grow_linestr() was reallocing the PL_linestr buffer and updating all
pointers within it, but was failing to update
PL_sublex_info.re_eval_start.

Unfortunately, lex_grow_linestr() doesn't seem to be used in core outside
of hereto docs, and due to a separate parser bug, hereto docs can't
currently be used within /(?{})/, so I can't add tests for it yet.

toke.c

diff --git a/toke.c b/toke.c
index f4394b5..19fa195 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -905,7 +905,7 @@ Perl_lex_grow_linestr(pTHX_ STRLEN len)
     SV *linestr;
     char *buf;
     STRLEN bufend_pos, bufptr_pos, oldbufptr_pos, oldoldbufptr_pos;
-    STRLEN linestart_pos, last_uni_pos, last_lop_pos;
+    STRLEN linestart_pos, last_uni_pos, last_lop_pos, re_eval_start_pos;
     linestr = PL_parser->linestr;
     buf = SvPVX(linestr);
     if (len <= SvLEN(linestr))
@@ -917,7 +917,11 @@ Perl_lex_grow_linestr(pTHX_ STRLEN len)
     linestart_pos = PL_parser->linestart - buf;
     last_uni_pos = PL_parser->last_uni ? PL_parser->last_uni - buf : 0;
     last_lop_pos = PL_parser->last_lop ? PL_parser->last_lop - buf : 0;
+    re_eval_start_pos = PL_sublex_info.re_eval_start ?
+                            PL_sublex_info.re_eval_start - buf : 0;
+
     buf = sv_grow(linestr, len);
+
     PL_parser->bufend = buf + bufend_pos;
     PL_parser->bufptr = buf + bufptr_pos;
     PL_parser->oldbufptr = buf + oldbufptr_pos;
@@ -927,6 +931,8 @@ Perl_lex_grow_linestr(pTHX_ STRLEN len)
        PL_parser->last_uni = buf + last_uni_pos;
     if (PL_parser->last_lop)
        PL_parser->last_lop = buf + last_lop_pos;
+    if (PL_sublex_info.re_eval_start)
+        PL_sublex_info.re_eval_start  = buf + re_eval_start_pos;
     return buf;
 }