diff options
author | Nicholas Clark <nick@ccl4.org> | 2006-05-28 10:40:48 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2006-05-28 10:40:48 +0000 |
commit | 9f76984545c78a615ef3f2522fb5b77578e41023 (patch) | |
tree | 887de5508973ef722c2714e691af75d638f19430 /hv.c | |
parent | eb7d7d25d2f780edcbedc124a5bdca0d53ad8687 (diff) | |
download | perl-9f76984545c78a615ef3f2522fb5b77578e41023.tar.gz |
Perl_refcounted_he_chain_2hv()'s code to skip duplicate keys was far
too lax.
p4raw-id: //depot/perl@28320
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 21 |
1 files changed, 20 insertions, 1 deletions
@@ -2634,7 +2634,26 @@ Perl_refcounted_he_chain_2hv(pTHX_ const struct refcounted_he *chain) for (; entry; entry = HeNEXT(entry)) { if (HeHASH(entry) == hash) { - goto next_please; + /* We might have a duplicate key here. If so, entry is older + than the key we've already put in the hash, so if they are + the same, skip adding entry. */ +#ifdef USE_ITHREADS + const STRLEN klen = HeKLEN(entry); + const char *const key = HeKEY(entry); + if (klen == chain->refcounted_he_keylen + && (!!HeKUTF8(entry) + == !!(chain->refcounted_he_data[0] & HVhek_UTF8)) + && memEQ(key, REF_HE_KEY(chain), klen)) + goto next_please; +#else + if (HeKEY_hek(entry) == chain->refcounted_he_hek) + goto next_please; + if (HeKLEN(entry) == HEK_LEN(chain->refcounted_he_hek) + && HeKUTF8(entry) == HEK_UTF8(chain->refcounted_he_hek) + && memEQ(HeKEY(entry), HEK_KEY(chain->refcounted_he_hek), + HeKLEN(entry))) + goto next_please; +#endif } } assert (!entry); |