This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Allow COW PVMGs to be tied
authorFather Chrysostomos <sprout@cpan.org>
Fri, 2 Dec 2011 06:46:22 +0000 (22:46 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 2 Dec 2011 06:46:22 +0000 (22:46 -0800)
commite7d0a3fbd986e18585e457528529ce365ace620e
tree861106bb893bba99fa58e41951ce03010b3a8cbb
parenta82b195bcec8edceae8d7f710b71cfcb1e8b1845
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[]}
sv.c
t/op/tie.t