In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/e7d0a3fbd986e18585e457528529ce365ace620e?hp=a82b195bcec8edceae8d7f710b71cfcb1e8b1845>

- Log -----------------------------------------------------------------
commit e7d0a3fbd986e18585e457528529ce365ace620e
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Thu Dec 1 22:46:22 2011 -0800

    Allow COW PVMGs to be tied
    
    This logic in sv_magic is wrong:
    
        if (SvREADONLY(sv)) {
        if (
            /* its okay to attach magic to shared strings; the subsequent
             * upgrade to PVMG will unshare the string */
            !(SvFAKE(sv) && SvTYPE(sv) < SVt_PVMG)
    
            && IN_PERL_RUNTIME
            && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how)
           )
        {
            Perl_croak_no_modify(aTHX);
        }
        }
    
    There is nothing wrong with attaching magic to a shared string that
    will stay shared.  Also, shared strings are not always < SVt_PVMG.
     Sometimes a PVMG or PVLV can end up with a shared string.  In those
    cases, the logic above treats them as read-only, which they ain’t.
    
    The easiest example is a downgraded typeglob:
    
    $x = *foo;        # now a PVGV
    undef $x ;        # downgraded to PVMG
    $x = __PACKAGE__; # now a shared string (COW)
    tie $x, "main";   # bang! $x is considered read-only
    sub main::TIESCALAR{bless[]}
-----------------------------------------------------------------------

Summary of changes:
 sv.c       |    5 ++---
 t/op/tie.t |   21 +++++++++++++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/sv.c b/sv.c
index 99d0d5c..ee64e1f 100644
--- a/sv.c
+++ b/sv.c
@@ -5299,9 +5299,8 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, 
const int how,
 #endif
     if (SvREADONLY(sv)) {
        if (
-           /* its okay to attach magic to shared strings; the subsequent
-            * upgrade to PVMG will unshare the string */
-           !(SvFAKE(sv) && SvTYPE(sv) < SVt_PVMG)
+           /* its okay to attach magic to shared strings */
+           (!SvFAKE(sv) || isGV_with_GP(sv))
 
            && IN_PERL_RUNTIME
            && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how)
diff --git a/t/op/tie.t b/t/op/tie.t
index 887fa96..bbd789c 100644
--- a/t/op/tie.t
+++ b/t/op/tie.t
@@ -1008,6 +1008,27 @@ print "ok\n";
 EXPECT
 ok
 ########
+#
+# Nor should it be impossible to tie COW scalars that are already PVMGs.
+
+sub TIESCALAR { bless [] }
+$x = *foo;        # PVGV
+undef $x;         # downgrade to PVMG
+$x = __PACKAGE__; # PVMG + COW
+tie $x, "";       # bang!
+
+print STDERR "ok\n";
+
+# However, one should not be able to tie read-only glob copies, which look
+# a bit like kine internally (FAKE + READONLY).
+$y = *foo;
+Internals::SvREADONLY($y,1);
+tie $y, "";
+
+EXPECT
+ok
+Modification of a read-only value attempted at - line 16.
+########
 
 # tied() should still work on tied scalars after glob assignment
 sub TIESCALAR {bless[]}

--
Perl5 Master Repository

Reply via email to