diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-07-12 11:54:15 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-07-12 13:00:03 -0700 |
commit | 3e89ba198c1cf083986263bd013ce43b4f206692 (patch) | |
tree | 51f85610ab3837a02b03c0f30a3b8a066ab0a2f0 /universal.c | |
parent | fa819c1ce3252e7ae97e9cdd4d3d0dd1edb06fa1 (diff) | |
download | perl-3e89ba198c1cf083986263bd013ce43b4f206692.tar.gz |
Make Internals::SvREADONLY smarter
(aka: More fun with Hash::Util)
$ perl -lMHash::Util=lock_value
$h{a} = __PACKAGE__; lock_value %h, a; $h{a} = "3"; print $h{a}'
^D
3
OK, so it didn’t really lock it. Now for more fun:
$ perl -lMHash::Util=unlock_value
$h{a} = __PACKAGE__; unlock_value %h, a; $h{a} =~ y/ia/ao/;
print __PACKAGE__
^D
moan
There are three different ways to fix this:
1) Add an SvFAKE function to Internals:: (not *more* ‘internals’ for
people [ahem, Const::Fast, ahem] to abuse!)
2) Use B::* functions in Hash::Util to check the flags (too slow)
3) Make Internals::SvREADONLY less ‘internal’, by having it deal with
readonliness in general, rather than just the SVf_READONLY flag.
The third approach seems the most logical, so that’s what this
commit does.
There is one test in t/op/tr.t that uses Internals::SvREADONLY to
detect bovinity, so I’ve changed it to use B instead, as that will
have no effect on post-install efficiency.
(This approach also fixes Const::Fast’s bugginess, but that is purely
accidental.)
Diffstat (limited to 'universal.c')
-rw-r--r-- | universal.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/universal.c b/universal.c index 35d1bcc7fe..3295fc51d9 100644 --- a/universal.c +++ b/universal.c @@ -777,19 +777,20 @@ XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */ sv = SvRV(svz); if (items == 1) { - if (SvREADONLY(sv)) + if (SvREADONLY(sv) && !SvIsCOW(sv)) XSRETURN_YES; else XSRETURN_NO; } else if (items == 2) { if (SvTRUE(ST(1))) { + if (SvIsCOW(sv)) sv_force_normal(sv); SvREADONLY_on(sv); XSRETURN_YES; } else { /* I hope you really know what you are doing. */ - SvREADONLY_off(sv); + if (!SvIsCOW(sv)) SvREADONLY_off(sv); XSRETURN_NO; } } |