summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-05-29 20:39:33 -0700
committerFlorian Ragwitz <rafl@debian.org>2011-09-05 01:09:54 +0200
commit8eae80dff0b7fb7ecfac92d00f7dc4aefc6ddc0c (patch)
tree514e9f44a9b3d6dcc3e89ffae85162dbb8959a06
parent27ccfd4fae9d5e2aa941173d7ca0eff458abc5ca (diff)
downloadperl-8eae80dff0b7fb7ecfac92d00f7dc4aefc6ddc0c.tar.gz
2nd try: [perl #91834] utf8::decode does not respect copy-on-write
I reverted the first version of this patch because I put the if() statement before a declaration. I did a revert, rather than a correc- tion, to make back-porting easier.
-rw-r--r--lib/utf8.t12
-rw-r--r--universal.c4
2 files changed, 15 insertions, 1 deletions
diff --git a/lib/utf8.t b/lib/utf8.t
index ae81ccdc46..6cd2d3fe30 100644
--- a/lib/utf8.t
+++ b/lib/utf8.t
@@ -427,6 +427,18 @@ SKIP: {
}
{
+ # Make sure utf8::decode respects copy-on-write [perl #91834].
+ # Hash keys are the easiest way to test this.
+ my $name = "\x{c3}\x{b3}";
+ my ($k1) = keys %{ { $name=>undef } };
+ my $k2 = $name;
+ utf8::decode($k1);
+ utf8::decode($k2);
+ my $h = { $k1 => 1, $k2 => 2 };
+ is join('', keys %$h), $k2, 'utf8::decode respects copy-on-write';
+}
+
+{
my $a = "456\xb6";
utf8::upgrade($a);
diff --git a/universal.c b/universal.c
index 07bbe96504..092ee80079 100644
--- a/universal.c
+++ b/universal.c
@@ -695,7 +695,9 @@ XS(XS_utf8_decode)
croak_xs_usage(cv, "sv");
else {
SV * const sv = ST(0);
- const bool RETVAL = sv_utf8_decode(sv);
+ bool RETVAL;
+ if (SvIsCOW(sv)) sv_force_normal(sv);
+ RETVAL = sv_utf8_decode(sv);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}