This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #79074] make sure HeSVKEY_force() preserves UTF8ness (pvn)
authorTony Cook <tony@develop-help.com>
Wed, 11 Sep 2013 06:30:43 +0000 (16:30 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 16 Sep 2013 04:16:03 +0000 (14:16 +1000)
HeSVKEY_force() is only used in two places in core.

In the first case, the key is always stored as a SV (when handling tie
magic, since NEXTKEY can only return a SV)

The second case is in B::HE, but I don't see a way to create a B::HE object
from a hash.

ext/XS-APItest/APItest.xs
ext/XS-APItest/t/hash.t
hv.h

index 16d26de..0e730b0 100644 (file)
@@ -1534,6 +1534,22 @@ refcounted_he_fetch(key, level=0)
 
 #endif
 
+void
+test_force_keys(HV *hv)
+    PREINIT:
+        HE *he;
+       STRLEN count = 0;
+    PPCODE:
+        hv_iterinit(hv);
+        he = hv_iternext(hv);
+        while (he) {
+           SV *sv = HeSVKEY_force(he);
+           ++count;
+           EXTEND(SP, count);
+           PUSHs(sv_mortalcopy(sv));
+            he = hv_iternext(hv);
+        }
+
 =pod
 
 sub TIEHASH  { bless {}, $_[0] }
index 9e27af8..8a8c607 100644 (file)
@@ -274,6 +274,13 @@ eval q{
 };
 pass("hv_store works on the hint hash");
 
+{
+    # [perl #79074] HeSVKEY_force loses UTF8ness
+    my %hash = ( "\xff" => 1, "\x{100}" => 1 );
+    my @keys = sort ( XS::APItest::Hash::test_force_keys(\%hash) );
+    is_deeply(\@keys, [ sort keys %hash ], "check HeSVKEY_force()");
+}
+
 done_testing;
 exit;
 
diff --git a/hv.h b/hv.h
index 920fd99..fa13a84 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -367,7 +367,9 @@ C<SV*>.
                                 ((HeKLEN(he) == HEf_SVKEY) ?           \
                                  HeKEY_sv(he) :                        \
                                  newSVpvn_flags(HeKEY(he),             \
-                                                HeKLEN(he), SVs_TEMP)) : \
+                                                 HeKLEN(he),            \
+                                                 SVs_TEMP |             \
+                                      ( HeKUTF8(he) ? SVf_UTF8 : 0 ))) : \
                                 &PL_sv_undef)
 #define HeSVKEY_set(he,sv)     ((HeKLEN(he) = HEf_SVKEY), (HeKEY_sv(he) = sv))