summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2003-04-26 19:45:28 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2003-04-27 05:59:39 +0000
commit34c3c4e3c36afb477dacf54a0d4557360c741870 (patch)
treefe7d672ae9542b2f7c7ad42bd416664a52cf3992 /hv.c
parent00cb5da129a8590d61ea16748bc9227b1757d0bf (diff)
downloadperl-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.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/hv.c b/hv.c
index 438042b252..5abfc62eaf 100644
--- a/hv.c
+++ b/hv.c
@@ -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 */