From 89f69032d6a71f41b96ae6becbf3df4e2f9509a5 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Sat, 27 Apr 2019 13:56:39 -0600 Subject: [PATCH] S_scan_const() Properly test if need to grow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we parse the input, creating a string constant, we may have to grow the destination if it fills up as we go along. It allocates space in an SV and populates the string, but it doesn' update the SvCUR until the end, so in single stepping the debugger through the code, the SV looks empty until the end. It turns out that as a result SvEND also doesn't get updated and still points to the beginning of the string until SvCUR is finally set. That means that the test changed by this commit was always succeeding, because it was using SvEND that didn't get updated, so it would attempt to grow each time through the loop. By moving a couple of statements earlier, and using SvLEN instead, which does always have the correct value, those extra growth attempts are avoided. Signed-off-by: Petr Písař --- toke.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/toke.c b/toke.c index 68eea0cae6..03c4f2ba26 100644 --- a/toke.c +++ b/toke.c @@ -4097,10 +4097,12 @@ S_scan_const(pTHX_ char *start) goto default_action; /* Redo, having upgraded so both are UTF-8 */ } else { /* UTF8ness matters: convert this non-UTF8 source char to - UTF-8 for output. It will occupy 2 bytes */ - if (d + 2 >= SvEND(sv)) { - const STRLEN extra = 2 + (send - s - 1) + 1; - const STRLEN off = d - SvPVX_const(sv); + UTF-8 for output. It will occupy 2 bytes, but don't include + the input byte since we haven't incremented 's' yet. See + Note on sizing above. */ + const STRLEN off = d - SvPVX(sv); + const STRLEN extra = 2 + (send - s - 1) + 1; + if (off + extra > SvLEN(sv)) { d = off + SvGROW(sv, off + extra); } *d++ = UTF8_EIGHT_BIT_HI(*s); -- 2.20.1