diff options
author | Father Chrysostomos <sprout@cpan.org> | 2016-07-27 22:09:42 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2016-07-27 22:10:17 -0700 |
commit | 2ca4363ddd9d355a31563ffe59eba09fcb54a708 (patch) | |
tree | 771ad86aa6016a27b3c3d70e55c8d54625478a0c /toke.c | |
parent | f8c1150140e8f939dc97b3c3554dd59f92b7b0af (diff) | |
download | perl-2ca4363ddd9d355a31563ffe59eba09fcb54a708.tar.gz |
[perl #128747] Fix line number bug with s//<<END/e
In commit 6745174b561 I changed the multi_open and multi_close
parser pastruct members (known as PL_multi_open/close in toke.c) from
char to UV.
I failed to change the localization code in S_sublex_start:
SAVEI8(PL_multi_close);
So on big-endian architectures only the most significant byte would be
localized. That meant that effectively no localization would happen
for ASCII string delimiters.
In S_sublex_done:
LEAVE;
if (PL_multi_close == '<')
PL_parser->herelines += l - PL_multi_end;
That LEAVE undoes the localization. '<' for PL_multi_close is a spe-
cial value that can only happen for here-docs. The ->herelines line
makes sure that line numbers are correct after a here-doc.
What ended up happening was that s//<<END/e would throw off line num-
bers after the here-doc body. PL_multi_close would end up being set
to '<', not '/', when the lexer was finishing up the s///, so it
treated it like a here-doc and screwed things up. This resulted in
the test failures in ticket #128747.
I found that we also had a bug on little-endian machines. But to get
the localization of the *least* sigificant byte to screw things up,
you have to try something other than s//<<END/e:
use utf8;
<<END;
${
#line 57
qq || }
END
warn; # line 59
Replace the pipes with lightning bolts:
use utf8;
<<END;
${
#line 57
qq ϟϟ }
END
warn; # line 7
and you get line 7 instead of 59. In this case, the inner construct
has a delimiter character whose code is > 255, but only the lower
8 bits get localized. So when the localization unwinds, you get
ord("ϟ") & 0xff | ord("<") instead of just ord("<"), resulting in the
here-doc line number handling being skipped.
This commit fixes the localization and adds the little-endian test.
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -2365,7 +2365,7 @@ S_sublex_push(pTHX) SAVEI32(PL_parser->herelines); PL_parser->herelines = 0; } - SAVEI8(PL_multi_close); + SAVEIV(PL_multi_close); SAVEPPTR(PL_bufptr); SAVEPPTR(PL_bufend); SAVEPPTR(PL_oldbufptr); |