|
@@ -302,8 +302,8 @@ ht_string_hash(const char *s)
|
|
|
} \
|
|
|
}
|
|
|
|
|
|
-#define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn, \
|
|
|
- reallocfn, freefn) \
|
|
|
+#define HT_GENERATE2(name, type, field, hashfn, eqfn, load, reallocarrayfn, \
|
|
|
+ freefn) \
|
|
|
/* Primes that aren't too far from powers of two. We stop at */ \
|
|
|
/* P=402653189 because P*sizeof(void*) is less than SSIZE_MAX */ \
|
|
|
/* even on a 32-bit platform. */ \
|
|
@@ -336,7 +336,7 @@ ht_string_hash(const char *s)
|
|
|
new_load_limit = (unsigned)(load*new_len); \
|
|
|
} while (new_load_limit <= size && \
|
|
|
prime_idx < (int)name##_N_PRIMES); \
|
|
|
- if ((new_table = mallocfn(new_len*sizeof(struct type*)))) { \
|
|
|
+ if ((new_table = reallocarrayfn(NULL, new_len, sizeof(struct type*)))) { \
|
|
|
unsigned b; \
|
|
|
memset(new_table, 0, new_len*sizeof(struct type*)); \
|
|
|
for (b = 0; b < head->hth_table_length; ++b) { \
|
|
@@ -356,7 +356,7 @@ ht_string_hash(const char *s)
|
|
|
head->hth_table = new_table; \
|
|
|
} else { \
|
|
|
unsigned b, b2; \
|
|
|
- new_table = reallocfn(head->hth_table, new_len*sizeof(struct type*)); \
|
|
|
+ new_table = reallocarrayfn(head->hth_table, new_len, sizeof(struct type*)); \
|
|
|
if (!new_table) return -1; \
|
|
|
memset(new_table + head->hth_table_length, 0, \
|
|
|
(new_len - head->hth_table_length)*sizeof(struct type*)); \
|
|
@@ -427,6 +427,21 @@ ht_string_hash(const char *s)
|
|
|
return 0; \
|
|
|
}
|
|
|
|
|
|
+#define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn, \
|
|
|
+ reallocfn, freefn) \
|
|
|
+ static void * \
|
|
|
+ name##_reallocarray(void *arg, size_t a, size_t b) \
|
|
|
+ { \
|
|
|
+ if ((b) && (a) > SIZE_MAX / (b)) \
|
|
|
+ return NULL; \
|
|
|
+ if (arg) \
|
|
|
+ return reallocfn((arg),(a)*(b)); \
|
|
|
+ else \
|
|
|
+ return mallocfn((a)*(b)); \
|
|
|
+ } \
|
|
|
+ HT_GENERATE2(name, type, field, hashfn, eqfn, load, \
|
|
|
+ name##_reallocarray, freefn)
|
|
|
+
|
|
|
/** Implements an over-optimized "find and insert if absent" block;
|
|
|
* not meant for direct usage by typical code, or usage outside the critical
|
|
|
* path.*/
|