Subject: | [PATCH] Fix for shared hash key scalars |
Encode has a tendency to mangle shared hash key scalars, which have been around since 5.8.0.
A change I plan to make to perl will cause this bug to occur more often. See the attached patch.
Sometimes two SVs can share the same string buffer. Doing $string .= '' unconditionally will
prevent that, as any modification will force the sharing to stop. (One can also do SvPV_force in
XS to force the string to stop being shared.)
Subject: | open_3vCFe7fb.txt |
diff -rup Encode-2.47-25zXtR/Encode.pm Encode-2.47-K4VhvS/Encode.pm
--- Encode-2.47-25zXtR/Encode.pm 2012-08-14 22:36:19.000000000 -0700
+++ Encode-2.47-K4VhvS/Encode.pm 2012-11-03 23:14:33.000000000 -0700
@@ -145,7 +145,7 @@ sub clone_encoding($) {
sub encode($$;$) {
my ( $name, $string, $check ) = @_;
return undef unless defined $string;
- $string .= '' if ref $string; # stringify;
+ $string .= ''; # stringify;
$check ||= 0;
unless ( defined $name ) {
require Carp;
@@ -165,7 +165,7 @@ sub encode($$;$) {
sub decode($$;$) {
my ( $name, $octets, $check ) = @_;
return undef unless defined $octets;
- $octets .= '' if ref $octets;
+ $octets .= '';
$check ||= 0;
my $enc = find_encoding($name);
unless ( defined $enc ) {
diff -rup Encode-2.47-25zXtR/t/Encode.t Encode-2.47-K4VhvS/t/Encode.t
--- Encode-2.47-25zXtR/t/Encode.t 2009-09-07 07:57:26.000000000 -0700
+++ Encode-2.47-K4VhvS/t/Encode.t 2012-11-03 23:14:08.000000000 -0700
@@ -25,7 +25,7 @@ my @character_set = ('0'..'9', 'A'..'Z',
my @source = qw(ascii iso8859-1 cp1250);
my @destiny = qw(cp1047 cp37 posix-bc);
my @ebcdic_sets = qw(cp1047 cp37 posix-bc);
-plan test => 38+$n*@encodings + 2*@source*@destiny*@character_set + 2*@ebcdic_sets*256 + 6 + 2;
+plan test => 38+$n*@encodings + 2*@source*@destiny*@character_set + 2*@ebcdic_sets*256 + 6 + 4;
my $str = join('',map(chr($_),0x20..0x7E));
my $cpy = $str;
ok(length($str),from_to($cpy,'iso8859-1','Unicode'),"Length Wrong");
@@ -149,3 +149,14 @@ sub new { my $class = shift; bless [ @_
package main;
ok(decode(latin1 => Encode::Dummy->new("foobar")), "foobar");
ok(encode(utf8 => Encode::Dummy->new("foobar")), "foobar");
+
+# hash keys
+my $key = (keys %{{ "whatever\x{100}" => '' }})[0];
+my $kopy = $key;
+encode("UTF-16LE", $kopy, Encode::FB_CROAK);
+ok $key, "whatever\x{100}", 'encode with shared hash key scalars';
+undef $key;
+$key = (keys %{{ "whatever" => '' }})[0];
+$kopy = $key;
+decode("UTF-16LE", $kopy, Encode::FB_CROAK);
+ok $key, "whatever", 'decode with shared hash key scalars';