diff options
author | David Mitchell <davem@iabyn.com> | 2018-01-12 16:21:48 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2018-01-19 13:45:20 +0000 |
commit | 6d63cc8e88a2b96ed80956f16c0978d790bf4411 (patch) | |
tree | 8f0a480fbc708d6d8752f40d4d7fd3adbee6ea16 /doop.c | |
parent | c923a6996655868e1b5140e8e47c2514e006902b (diff) | |
download | perl-6d63cc8e88a2b96ed80956f16c0978d790bf4411.tar.gz |
tr///c: handle len(replacement charlist) > 32767
RT #132608
In the non-utf8 case, the /c (complement) flag to tr adds an implied
\x{100}-\x{7fffffff} range to the search charlist. If the replacement list
contains more chars than are paired with the 0-255 part of the search
list, then the excess chars are stored in an extended part of the table.
The excess char count was being stored as a short, which caused problems
if the replacement list contained more than 32767 excess chars: either
substituting the wrong char, or substituting for a char located up to
0xffff bytes in memory before the real translation table.
So change it to SSize_t.
Note that this is only a problem when the search and replacement charlists
are non-utf8, the replacement list contains around 0x8000+ entries, and
where the string being translated is utf8 with at least one codepoint >=
U+8000.
Diffstat (limited to 'doop.c')
-rw-r--r-- | doop.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -227,7 +227,7 @@ S_do_trans_complex(pTHX_ SV * const sv) if (complement) /* number of replacement chars in excess of any 0x00..0xff * search characters */ - excess = (SSize_t)extbl->excess_len; + excess = extbl->excess_len; if (PL_op->op_private & OPpTRANS_SQUASH) { UV pch = 0xfeedface; |