diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2003-04-26 19:45:28 +0100 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2003-04-27 05:59:39 +0000 |
commit | 34c3c4e3c36afb477dacf54a0d4557360c741870 (patch) | |
tree | fe7d672ae9542b2f7c7ad42bd416664a52cf3992 /hv.c | |
parent | 00cb5da129a8590d61ea16748bc9227b1757d0bf (diff) | |
download | perl-34c3c4e3c36afb477dacf54a0d4557360c741870.tar.gz |
Re: the revenge of the bride of the son of the night of the living pseudohashes
Message-ID: <20030426174528.GA9588@fdgroup.com>
p4raw-id: //depot/perl@19345
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 27 |
1 files changed, 24 insertions, 3 deletions
@@ -151,7 +151,7 @@ S_hv_notallowed(pTHX_ int flags, const char *key, I32 klen, } else { /* Need to free saved eventually assign to mortal SV */ - SV *sv = sv_newmortal(); + /* XXX is this line an error ???: SV *sv = sv_newmortal(); */ sv_usepvn(sv, (char *) key, klen); } if (flags & HVhek_UTF8) { @@ -1701,11 +1701,32 @@ Perl_hv_clear(pTHX_ HV *hv) if (!hv) return; + xhv = (XPVHV*)SvANY(hv); + if(SvREADONLY(hv)) { - Perl_croak(aTHX_ "Attempt to clear a restricted hash"); + /* restricted hash: convert all keys to placeholders */ + I32 i; + HE* entry; + for (i=0; i< (I32) xhv->xhv_max; i++) { + entry = ((HE**)xhv->xhv_array)[i]; + for (; entry; entry = HeNEXT(entry)) { + /* not already placeholder */ + if (HeVAL(entry) != &PL_sv_undef) { + if (HeVAL(entry) && SvREADONLY(HeVAL(entry))) { + SV* keysv = hv_iterkeysv(entry); + Perl_croak(aTHX_ + "Attempt to delete readonly key '%_' from a restricted hash", + keysv); + } + SvREFCNT_dec(HeVAL(entry)); + HeVAL(entry) = &PL_sv_undef; + xhv->xhv_placeholders++; /* HvPLACEHOLDERS(hv)++ */ + } + } + } + return; } - xhv = (XPVHV*)SvANY(hv); hfreeentries(hv); xhv->xhv_fill = 0; /* HvFILL(hv) = 0 */ xhv->xhv_keys = 0; /* HvKEYS(hv) = 0 */ |