summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2005-06-13 20:18:57 +0000
committerNicholas Clark <nick@ccl4.org>2005-06-13 20:18:57 +0000
commit5d2b148555a8ecf68ab82784915f0877e3c9783a (patch)
treeb712f0854fb7eda520a59754231b57cd8f2ff2fd /hv.c
parent848ef95539b9ac5bb84d1c24074fa4a1e19c3dfb (diff)
downloadperl-5d2b148555a8ecf68ab82784915f0877e3c9783a.tar.gz
Croak if an attempt is made to modify PL_strtab
(er, TODO - these should be in perldiag) p4raw-id: //depot/perl@24827
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/hv.c b/hv.c
index 3d2e5891e9..0157886b9d 100644
--- a/hv.c
+++ b/hv.c
@@ -33,6 +33,9 @@ holds the key and hash value.
#define HV_MAX_LENGTH_BEFORE_SPLIT 14
+static const char *const S_strtab_error
+ = "Cannot modify shared string table in hv_%s";
+
STATIC void
S_more_he(pTHX)
{
@@ -692,6 +695,14 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
unshare_hek (HeKEY_hek(entry));
HeKEY_hek(entry) = new_hek;
}
+ else if (hv == PL_strtab) {
+ /* PL_strtab is usually the only hash without HvSHAREKEYS,
+ so putting this test here is cheap */
+ if (flags & HVhek_FREEKEY)
+ Safefree(key);
+ Perl_croak(aTHX_ S_strtab_error,
+ action & HV_FETCH_LVALUE ? "fetch" : "store");
+ }
else
HeKFLAGS(entry) = masked_flags;
if (masked_flags & HVhek_ENABLEHVKFLAGS)
@@ -793,6 +804,14 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
bad API design. */
if (HvSHAREKEYS(hv))
HeKEY_hek(entry) = share_hek_flags(key, klen, hash, flags);
+ else if (hv == PL_strtab) {
+ /* PL_strtab is usually the only hash without HvSHAREKEYS, so putting
+ this test here is cheap */
+ if (flags & HVhek_FREEKEY)
+ Safefree(key);
+ Perl_croak(aTHX_ S_strtab_error,
+ action & HV_FETCH_LVALUE ? "fetch" : "store");
+ }
else /* gotta do the real thing */
HeKEY_hek(entry) = save_hek_flags(key, klen, hash, flags);
HeVAL(entry) = val;
@@ -1036,6 +1055,12 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8)
continue;
+ if (hv == PL_strtab) {
+ if (k_flags & HVhek_FREEKEY)
+ Safefree(key);
+ Perl_croak(aTHX_ S_strtab_error, "delete");
+ }
+
/* if placeholder is here, it's already been deleted.... */
if (HeVAL(entry) == &PL_sv_placeholder)
{