Skip to content

Commit

Permalink
Fix pointer hash function.
Browse files Browse the repository at this point in the history
* Use `uintptr_t` instead of `unsigned long`, as the latter is not
  necessarily the right size.
* Make the hash itself unsigned, and use only unsgined arithmetic to
  compute it, to avoid the possibility of signed overflow, which would
  invoke undefined behavior.

Inspired by the R repository.
  • Loading branch information
dag-erling committed Jul 30, 2024
1 parent 1e3f327 commit fd1e5c8
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions lib/xmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */

#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
Expand Down Expand Up @@ -71,18 +72,18 @@ hash_table_new(void)
return tbl;
}

static int
static unsigned int
hash_void_ptr(void *ptr)
{
int hash;
int i;
unsigned int hash;
unsigned int i;

/* I took this hash function just off the top of my head, I have
no idea whether it is bad or very bad. */
hash = 0;
for (i = 0; i < (int)sizeof(ptr)*8 / TABLE_BITS; i++)
for (i = 0; i < sizeof(ptr) * 8 / TABLE_BITS; i++)
{
hash ^= (unsigned long)ptr >> i*8;
hash ^= (uintptr_t)ptr >> i * 8;
hash += i * 17;
hash &= TABLE_MASK;
}
Expand All @@ -93,7 +94,7 @@ static void
hash_table_add(hashTable *tbl, void *ptr, size_t bytes,
const char *file, int line, const char *func)
{
int i;
unsigned int i;
hashTableItem *item, *new;

i = hash_void_ptr(ptr);
Expand Down

0 comments on commit fd1e5c8

Please sign in to comment.