Make utf8::encode respect magic
authorFather Chrysostomos <sprout@cpan.org>
Fri, 28 Sep 2012 15:34:51 +0000 (08:34 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 1 Oct 2012 19:51:54 +0000 (12:51 -0700)
It has always ignored set-magic, as far as I can tell.

Since the magic flags patch (4bac9ae47b), it has been ignor-
ing get- magic on magical scalars that were already PVs.
sv_utf8_upgrade_flags_grow begins with an if(!SvPOK(sv)) check, which
used to mean ‘if this scalar is magic or not a string’, but now means
simply ‘if this scalar is not a string’.  SvPOK_nog is the new SvPOK.

Due to the way the flags now work, I had to modify sv_pvutf8n_force
as well, to keep existing tests passing.

sv.c
t/op/utf8magic.t
universal.c

index 041cfaf..906c30e 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -3164,7 +3164,7 @@ Perl_sv_utf8_upgrade_flags_grow(pTHX_ register SV *const sv, const I32 flags, ST
 
     if (sv == &PL_sv_undef)
        return 0;
-    if (!SvPOK(sv)) {
+    if (!SvPOK_nog(sv)) {
        STRLEN len = 0;
        if (SvREADONLY(sv) && (SvPOKp(sv) || SvIOKp(sv) || SvNOKp(sv))) {
            (void) sv_2pv_flags(sv,&len, flags);
@@ -9123,7 +9123,7 @@ Perl_sv_pvutf8n_force(pTHX_ SV *const sv, STRLEN *const lp)
     PERL_ARGS_ASSERT_SV_PVUTF8N_FORCE;
 
     sv_pvn_force(sv,lp);
-    sv_utf8_upgrade(sv);
+    sv_utf8_upgrade_nomg(sv);
     *lp = SvCUR(sv);
     return SvPVX(sv);
 }
index 3d942c0..cc6936f 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 4;
+plan tests => 5;
 
 use strict;
 
@@ -23,3 +23,12 @@ $str =~ /(.)/;
 ok !utf8::is_utf8($1), "is_utf8(bytes)";
 scalar "$1"; # invoke SvGETMAGIC
 ok !utf8::is_utf8($1), "is_utf8(bytes)";
+
+sub TIESCALAR { bless [pop] }
+sub FETCH     { $_[0][0] }
+sub STORE     { $::stored = pop }
+
+tie my $str2, "", "a";
+$str2 = "b";
+utf8::encode $str2;
+is $::stored, "a", 'utf8::encode respects get-magic on POK scalars';
index cb49e0b..676c39b 100644 (file)
@@ -808,6 +808,7 @@ XS(XS_utf8_encode)
     if (items != 1)
        croak_xs_usage(cv, "sv");
     sv_utf8_encode(ST(0));
+    SvSETMAGIC(ST(0));
     XSRETURN_EMPTY;
 }