Mercurial > hg > octave-lojdl > gnulib-hg
changeset 13613:7f0f04d7017a
hash: factor, and guard against misbehaving hasher function
* lib/hash.c (safe_hasher): New function, to encapsulate the checking
of table->hasher's return value. Also protect against a hash value
so large that adding it to table->bucket results in a NULL pointer.
(hash_lookup, hash_get_next, hash_find_entry, transfer_entries):
Use it in place of open-coded check-and-abort.
author | Eric Blake <eblake@redhat.com> |
---|---|
date | Tue, 31 Aug 2010 10:10:32 +0200 |
parents | 37d5b2cb63ba |
children | f2950e788162 |
files | ChangeLog lib/hash.c |
diffstat | 2 files changed, 26 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-08-31 Eric Blake <eblake@redhat.com> + and Jim Meyering <meyering@redhat.com> + + hash: factor, and guard against misbehaving hasher function + * lib/hash.c (safe_hasher): New function, to encapsulate the checking + of table->hasher's return value. Also protect against a hash value + so large that adding it to table->bucket results in a NULL pointer. + (hash_lookup, hash_get_next, hash_find_entry, transfer_entries): + Use it in place of open-coded check-and-abort. + 2010-08-30 Bruno Haible <bruno@clisp.org> hash: silence spurious clang warning
--- a/lib/hash.c +++ b/lib/hash.c @@ -243,19 +243,26 @@ (unsigned long int) max_bucket_length); } +/* Hash KEY and return a pointer to the selected bucket. + If TABLE->hasher misbehaves, abort. */ +static struct hash_entry const * +safe_hasher (const Hash_table *table, const void *key) +{ + size_t n = table->hasher (key, table->n_buckets); + if (! (n < table->n_buckets)) + abort (); + return table->bucket + n; +} + /* If ENTRY matches an entry already in the hash table, return the entry from the table. Otherwise, return NULL. */ void * hash_lookup (const Hash_table *table, const void *entry) { - struct hash_entry const *bucket - = table->bucket + table->hasher (entry, table->n_buckets); + struct hash_entry const *bucket = safe_hasher (table, entry); struct hash_entry const *cursor; - if (! (bucket < table->bucket_limit)) - abort (); - if (bucket->data == NULL) return NULL; @@ -299,13 +306,9 @@ void * hash_get_next (const Hash_table *table, const void *entry) { - struct hash_entry const *bucket - = table->bucket + table->hasher (entry, table->n_buckets); + struct hash_entry const *bucket = safe_hasher (table, entry); struct hash_entry const *cursor; - if (! (bucket < table->bucket_limit)) - abort (); - /* Find next entry in the same bucket. */ cursor = bucket; do @@ -787,13 +790,9 @@ hash_find_entry (Hash_table *table, const void *entry, struct hash_entry **bucket_head, bool delete) { - struct hash_entry *bucket - = table->bucket + table->hasher (entry, table->n_buckets); + struct hash_entry *bucket = safe_hasher (table, entry); struct hash_entry *cursor; - if (! (bucket < table->bucket_limit)) - abort (); - *bucket_head = bucket; /* Test for empty bucket. */ @@ -878,10 +877,7 @@ for (cursor = bucket->next; cursor; cursor = next) { data = cursor->data; - new_bucket = (dst->bucket + dst->hasher (data, dst->n_buckets)); - - if (! (new_bucket < dst->bucket_limit)) - abort (); + new_bucket = safe_hasher (dst, data); next = cursor->next; @@ -908,10 +904,7 @@ bucket->next = NULL; if (safe) continue; - new_bucket = (dst->bucket + dst->hasher (data, dst->n_buckets)); - - if (! (new_bucket < dst->bucket_limit)) - abort (); + new_bucket = safe_hasher (dst, data); if (new_bucket->data) {