summaryrefslogtreecommitdiff
path: root/doop.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2018-01-12 16:21:48 +0000
committerDavid Mitchell <davem@iabyn.com>2018-01-19 13:45:20 +0000
commit6d63cc8e88a2b96ed80956f16c0978d790bf4411 (patch)
tree8f0a480fbc708d6d8752f40d4d7fd3adbee6ea16 /doop.c
parentc923a6996655868e1b5140e8e47c2514e006902b (diff)
downloadperl-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.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/doop.c b/doop.c
index fa908cf4fa..edc403838c 100644
--- a/doop.c
+++ b/doop.c
@@ -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;