From e7d0a3fbd986e18585e457528529ce365ace620e Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Thu, 1 Dec 2011 22:46:22 -0800 Subject: Allow COW PVMGs to be tied MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sv.c') diff --git a/sv.c b/sv.c index 99d0d5ca0f..ee64e1fe7d 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) -- cgit v1.2.1