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 /lib | |
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 'lib')
-rw-r--r-- | lib/B/Deparse.pm | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index 5fc3d02e1f..0b4fafc012 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -58,6 +58,8 @@ our $AUTOLOAD; use warnings (); require feature; +use Config; + BEGIN { # List version-specific constants here. # Easiest way to keep this code portable between version looks to @@ -5607,7 +5609,8 @@ sub collapse { sub tr_decode_byte { my($table, $flags) = @_; - my (@table) = unpack("s256sss*", $table); + my $ssize_t = $Config{ptrsize} == 8 ? 'q' : 'l'; + my (@table) = unpack("s256${ssize_t}ss*", $table); my ($excess_len, $repeat_char) = splice(@table, 256, 2); my($c, $tr, @from, @to, @delfrom, $delhyphen); |