}
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) {
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 */
chdir 't';
}
}
-use Test::More tests => 157;
+use Test::More tests => 155;
use strict;
my @Exported_Funcs;
is( $hash{locked}, 42, 'unlock_value' );
-TODO: {
-# local $TODO = 'assigning to a hash screws with locked keys';
-
+{
my %hash = ( foo => 42, locked => 23 );
lock_keys(%hash);
- lock_value(%hash, 'locked');
eval { %hash = ( wubble => 42 ) }; # we know this will bomb
- like( $@, qr/^Attempt to clear a restricted hash/ );
-
- eval { unlock_value(%hash, 'locked') }; # but this shouldn't
- is( $@, '', 'unlock_value() after denied assignment' );
-
- is_deeply( \%hash, { foo => 42, locked => 23 },
- 'hash should not be altered by denied assignment' );
+ like( $@, qr/^Attempt to access disallowed key 'wubble'/ );
unlock_keys(%hash);
}
lock_value(%hash, 'RO');
eval { %hash = (KEY => 1) };
- like( $@, qr/^Attempt to clear a restricted hash/ );
+ like( $@, qr/^Attempt to delete readonly key 'RO' from a restricted hash/ );
}
-# TODO: This should be allowed but it might require putting extra
-# code into aassign.
{
my %hash = (KEY => 1, RO => 2);
lock_keys(%hash);
eval { %hash = (KEY => 1, RO => 2) };
- like( $@, qr/^Attempt to clear a restricted hash/ );
+ is( $@, '');
}
(F) The failing code has attempted to get or set a key which is not in
the current set of allowed keys of a restricted hash.
-=item Attempt to clear a restricted hash
-
-(F) It is currently not allowed to clear a restricted hash, even if the
-new hash would contain the same keys as before. This may change in
-the future.
-
=item Attempt to delete readonly key '%s' from a restricted hash
(F) The failing code attempted to delete a key whose value has been