* src/hash.c (jash_string): [SV 54980] Avoid ASAN error

This commit is contained in:
Paul Smith 2019-05-13 18:45:18 -04:00
parent b5de783f77
commit 9ce370249b
2 changed files with 32 additions and 27 deletions

View File

@ -47,7 +47,7 @@ hash_init (struct hash_table *ht, unsigned long size,
if (ht->ht_vec == 0) if (ht->ht_vec == 0)
{ {
fprintf (stderr, _("can't allocate %lu bytes for hash table: memory exhausted"), fprintf (stderr, _("can't allocate %lu bytes for hash table: memory exhausted"),
ht->ht_size * (unsigned long) sizeof (struct token *)); ht->ht_size * (unsigned long) sizeof (struct token *));
exit (MAKE_TROUBLE); exit (MAKE_TROUBLE);
} }
@ -95,22 +95,22 @@ hash_find_slot (struct hash_table *ht, const void *key)
slot = &ht->ht_vec[hash_1]; slot = &ht->ht_vec[hash_1];
if (*slot == 0) if (*slot == 0)
return (deleted_slot ? deleted_slot : slot); return (deleted_slot ? deleted_slot : slot);
if (*slot == hash_deleted_item) if (*slot == hash_deleted_item)
{ {
if (deleted_slot == 0) if (deleted_slot == 0)
deleted_slot = slot; deleted_slot = slot;
} }
else else
{ {
if (key == *slot) if (key == *slot)
return slot; return slot;
if ((*ht->ht_compare) (key, *slot) == 0) if ((*ht->ht_compare) (key, *slot) == 0)
return slot; return slot;
ht->ht_collisions++; ht->ht_collisions++;
} }
if (!hash_2) if (!hash_2)
hash_2 = (*ht->ht_hash_2) (key) | 1; hash_2 = (*ht->ht_hash_2) (key) | 1;
hash_1 += hash_2; hash_1 += hash_2;
} }
} }
@ -139,7 +139,7 @@ hash_insert_at (struct hash_table *ht, const void *item, const void *slot)
{ {
ht->ht_fill++; ht->ht_fill++;
if (old_item == 0) if (old_item == 0)
ht->ht_empty_slots--; ht->ht_empty_slots--;
old_item = item; old_item = item;
} }
*(void const **) slot = item; *(void const **) slot = item;
@ -182,7 +182,7 @@ hash_free_items (struct hash_table *ht)
{ {
void *item = *vec; void *item = *vec;
if (!HASH_VACANT (item)) if (!HASH_VACANT (item))
free (item); free (item);
*vec = 0; *vec = 0;
} }
ht->ht_fill = 0; ht->ht_fill = 0;
@ -227,7 +227,7 @@ hash_map (struct hash_table *ht, hash_map_func_t map)
for (slot = ht->ht_vec; slot < end; slot++) for (slot = ht->ht_vec; slot < end; slot++)
{ {
if (!HASH_VACANT (*slot)) if (!HASH_VACANT (*slot))
(*map) (*slot); (*map) (*slot);
} }
} }
@ -240,7 +240,7 @@ hash_map_arg (struct hash_table *ht, hash_map_arg_func_t map, void *arg)
for (slot = ht->ht_vec; slot < end; slot++) for (slot = ht->ht_vec; slot < end; slot++)
{ {
if (!HASH_VACANT (*slot)) if (!HASH_VACANT (*slot))
(*map) (*slot, arg); (*map) (*slot, arg);
} }
} }
@ -264,10 +264,10 @@ hash_rehash (struct hash_table *ht)
for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++) for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++)
{ {
if (! HASH_VACANT (*ovp)) if (! HASH_VACANT (*ovp))
{ {
void **slot = hash_find_slot (ht, *ovp); void **slot = hash_find_slot (ht, *ovp);
*slot = *ovp; *slot = *ovp;
} }
} }
ht->ht_empty_slots = ht->ht_size - ht->ht_fill; ht->ht_empty_slots = ht->ht_size - ht->ht_fill;
free (old_vec); free (old_vec);
@ -277,12 +277,12 @@ void
hash_print_stats (struct hash_table *ht, FILE *out_FILE) hash_print_stats (struct hash_table *ht, FILE *out_FILE)
{ {
fprintf (out_FILE, _("Load=%lu/%lu=%.0f%%, "), ht->ht_fill, ht->ht_size, fprintf (out_FILE, _("Load=%lu/%lu=%.0f%%, "), ht->ht_fill, ht->ht_size,
100.0 * (double) ht->ht_fill / (double) ht->ht_size); 100.0 * (double) ht->ht_fill / (double) ht->ht_size);
fprintf (out_FILE, _("Rehash=%u, "), ht->ht_rehashes); fprintf (out_FILE, _("Rehash=%u, "), ht->ht_rehashes);
fprintf (out_FILE, _("Collisions=%lu/%lu=%.0f%%"), ht->ht_collisions, ht->ht_lookups, fprintf (out_FILE, _("Collisions=%lu/%lu=%.0f%%"), ht->ht_collisions, ht->ht_lookups,
(ht->ht_lookups (ht->ht_lookups
? (100.0 * (double) ht->ht_collisions / (double) ht->ht_lookups) ? (100.0 * (double) ht->ht_collisions / (double) ht->ht_lookups)
: 0)); : 0));
} }
/* Dump all items into a NULL-terminated vector. Use the /* Dump all items into a NULL-terminated vector. Use the
@ -329,7 +329,7 @@ round_up_2 (unsigned long n)
} }
#define rol32(v, n) \ #define rol32(v, n) \
((v) << (n) | ((v) >> (32 - (n)))) ((v) << (n) | ((v) >> (32 - (n))))
/* jhash_mix -- mix 3 32-bit values reversibly. */ /* jhash_mix -- mix 3 32-bit values reversibly. */
#define jhash_mix(a, b, c) \ #define jhash_mix(a, b, c) \
@ -446,6 +446,9 @@ unsigned jhash(unsigned const char *k, int length)
} while (0) } while (0)
#endif #endif
/* This function performs magic which is correct but causes ASAN heartburn
when we pass in a global constant string (at least). */
__attribute__((no_sanitize_address))
unsigned jhash_string(unsigned const char *k) unsigned jhash_string(unsigned const char *k)
{ {
unsigned int a, b, c; unsigned int a, b, c;

View File

@ -179,6 +179,8 @@ sub toplevel
foreach (# UNIX-specific things foreach (# UNIX-specific things
'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH', 'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH',
'LD_LIBRARY_PATH', 'LD_LIBRARY_PATH',
# SAN things
'ASAN_OPTIONS', 'UBSAN_OPTIONS',
# Purify things # Purify things
'PURIFYOPTIONS', 'PURIFYOPTIONS',
# Windows NT-specific stuff # Windows NT-specific stuff