diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-09-19 23:12:48 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-09-20 09:25:02 -0700 |
commit | a623f8939cbcaa58a069807591675c0ebcd4135b (patch) | |
tree | 6e4f3122df0aefeac3b4eb007f9b869a850c6df9 /sv.c | |
parent | fd01b4b766a3276a9439cade9b1a047c37876c1b (diff) | |
download | perl-a623f8939cbcaa58a069807591675c0ebcd4135b.tar.gz |
Implement the bipolar read-only system
This fixes bugs related to Hash::Util::unlock accidentally unlocking
internal scalars (e.g., that returned by undef()) and allowing them to
be modified.
Internal read-only values are now marked by two flags, the regular
read-only flag, and the new ‘protected’ flag.
Before this SvREADONLY served two purposes:
1) The code would use it to protect things that must not be modi-
fied, ever (except when the core sees fit to do so).
2) Hash::Util and everybody else would use it to make this unmodifia-
ble temporarily when requested by the user.
Internals::SvREADONLY serves the latter purpose and only flips the
read-only flag, so things that need to stay read-only will remain so,
because of the ‘other’ read-only flag, that CPAN doesn’t know about.
(If you are a CPAN author, do not read this.)
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -4499,7 +4499,8 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) /* slated for free anyway (and not COW)? */ (sflags & (SVs_TEMP|SVf_IsCOW)) == SVs_TEMP /* or a swipable TARG */ - || ((sflags & (SVs_PADTMP|SVf_READONLY|SVf_IsCOW)) + || ((sflags & + (SVs_PADTMP|SVf_READONLY|SVf_PROTECT|SVf_IsCOW)) == SVs_PADTMP /* whose buffer is worth stealing */ && CHECK_COWBUF_THRESHOLD(cur,len) @@ -10071,7 +10072,7 @@ Perl_sv_bless(pTHX_ SV *const sv, HV *const stash) if (!SvROK(sv)) Perl_croak(aTHX_ "Can't bless non-reference value"); tmpRef = SvRV(sv); - if (SvFLAGS(tmpRef) & (SVs_OBJECT|SVf_READONLY)) { + if (SvFLAGS(tmpRef) & (SVs_OBJECT|SVf_READONLY|SVf_PROTECT)) { if (SvREADONLY(tmpRef)) Perl_croak_no_modify(); if (SvOBJECT(tmpRef)) { @@ -14875,18 +14876,18 @@ void Perl_init_constants(pTHX) { SvREFCNT(&PL_sv_undef) = SvREFCNT_IMMORTAL; - SvFLAGS(&PL_sv_undef) = SVf_READONLY|SVt_NULL; + SvFLAGS(&PL_sv_undef) = SVf_READONLY|SVf_PROTECT|SVt_NULL; SvANY(&PL_sv_undef) = NULL; SvANY(&PL_sv_no) = new_XPVNV(); SvREFCNT(&PL_sv_no) = SvREFCNT_IMMORTAL; - SvFLAGS(&PL_sv_no) = SVt_PVNV|SVf_READONLY + SvFLAGS(&PL_sv_no) = SVt_PVNV|SVf_READONLY|SVf_PROTECT |SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK |SVp_POK|SVf_POK; SvANY(&PL_sv_yes) = new_XPVNV(); SvREFCNT(&PL_sv_yes) = SvREFCNT_IMMORTAL; - SvFLAGS(&PL_sv_yes) = SVt_PVNV|SVf_READONLY + SvFLAGS(&PL_sv_yes) = SVt_PVNV|SVf_READONLY|SVf_PROTECT |SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK |SVp_POK|SVf_POK; |