summaryrefslogtreecommitdiff
path: root/universal.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-07-12 11:54:15 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-07-12 13:00:03 -0700
commit3e89ba198c1cf083986263bd013ce43b4f206692 (patch)
tree51f85610ab3837a02b03c0f30a3b8a066ab0a2f0 /universal.c
parentfa819c1ce3252e7ae97e9cdd4d3d0dd1edb06fa1 (diff)
downloadperl-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.c5
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;
}
}