HT_PROTOTYPE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
strmap_entries_eq)
-HT_GENERATE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
- strmap_entries_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
+ strmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
HT_PROTOTYPE(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
digestmap_entries_eq)
-HT_GENERATE(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
- digestmap_entries_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
+ digestmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
/** Constructor to create a new empty map from strings to void*'s.
*/
HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
cached_getaddrinfo_item_hash,
cached_getaddrinfo_items_eq);
-HT_GENERATE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
- cached_getaddrinfo_item_hash,
- cached_getaddrinfo_items_eq,
- 0.6, tor_malloc_, tor_realloc_, tor_free_);
+HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
+ cached_getaddrinfo_item_hash,
+ cached_getaddrinfo_items_eq,
+ 0.6, tor_reallocarray_, tor_free_)
int
sandbox_getaddrinfo(const char *name, const char *servname,
HT_PROTOTYPE(process_map, waitpid_callback_t, node, process_map_entry_hash_,
process_map_entries_eq_);
-HT_GENERATE(process_map, waitpid_callback_t, node, process_map_entry_hash_,
- process_map_entries_eq_, 0.6, malloc, realloc, free);
+HT_GENERATE2(process_map, waitpid_callback_t, node, process_map_entry_hash_,
+ process_map_entries_eq_, 0.6, tor_reallocarray_, tor_free_);
/**
* Begin monitoring the child pid <b>pid</b> to see if we get a SIGCHLD for
} \
}
-#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. */ \
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) { \
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*)); \
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.*/
HT_PROTOTYPE(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
channel_idmap_eq);
-HT_GENERATE(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
- channel_idmap_eq, 0.5, tor_malloc, tor_realloc, tor_free_);
+HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
+ channel_idmap_eq, 0.5, tor_reallocarray_, tor_free_);
static cell_queue_entry_t * cell_queue_entry_dup(cell_queue_entry_t *q);
static void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off);
chan_circid_map = HT_INITIALIZER();
HT_PROTOTYPE(chan_circid_map, chan_circid_circuit_map_t, node,
chan_circid_entry_hash_, chan_circid_entries_eq_)
-HT_GENERATE(chan_circid_map, chan_circid_circuit_map_t, node,
- chan_circid_entry_hash_, chan_circid_entries_eq_, 0.6,
- malloc, realloc, free)
+HT_GENERATE2(chan_circid_map, chan_circid_circuit_map_t, node,
+ chan_circid_entry_hash_, chan_circid_entries_eq_, 0.6,
+ tor_reallocarray_, tor_free_)
/** The most recently returned entry from circuit_get_by_circid_chan;
* used to improve performance when many cells arrive in a row from the
/* Emit a bunch of hash table stuff */
HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
chanid_circid_entry_hash, chanid_circid_entries_eq);
-HT_GENERATE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
- chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
- malloc, realloc, free);
+HT_GENERATE2(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
+ chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
+ tor_reallocarray_, tor_free_)
/*
* Circuitmux alloc/free functions
HT_PROTOTYPE(cache_map, cached_resolve_t, node, cached_resolve_hash,
cached_resolves_eq)
-HT_GENERATE(cache_map, cached_resolve_t, node, cached_resolve_hash,
- cached_resolves_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(cache_map, cached_resolve_t, node, cached_resolve_hash,
+ cached_resolves_eq, 0.6, tor_reallocarray_, tor_free_)
/** Initialize the DNS cache. */
static void
HT_PROTOTYPE(fp_pair_map_impl, fp_pair_map_entry_s, node,
fp_pair_map_entry_hash, fp_pair_map_entries_eq)
-HT_GENERATE(fp_pair_map_impl, fp_pair_map_entry_s, node,
- fp_pair_map_entry_hash, fp_pair_map_entries_eq,
- 0.6, tor_malloc, tor_realloc, tor_free)
+HT_GENERATE2(fp_pair_map_impl, fp_pair_map_entry_s, node,
+ fp_pair_map_entry_hash, fp_pair_map_entries_eq,
+ 0.6, tor_reallocarray_, tor_free_)
/** Constructor to create a new empty map from fp_pair_t to void *
*/
HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq);
-HT_GENERATE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
- clientmap_entries_eq, 0.6, malloc, realloc, free);
+HT_GENERATE2(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
+ clientmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
/** Free all storage held by <b>ent</b>. */
static void
HT_PROTOTYPE(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
dirreq_map_ent_eq);
-HT_GENERATE(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
- dirreq_map_ent_eq, 0.6, malloc, realloc, free);
+HT_GENERATE2(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
+ dirreq_map_ent_eq, 0.6, tor_reallocarray_, tor_free_)
/** Helper: Put <b>entry</b> into map of directory requests using
* <b>type</b> and <b>dirreq_id</b> as key parts. If there is
HT_PROTOTYPE(microdesc_map, microdesc_t, node,
microdesc_hash_, microdesc_eq_);
-HT_GENERATE(microdesc_map, microdesc_t, node,
+HT_GENERATE2(microdesc_map, microdesc_t, node,
microdesc_hash_, microdesc_eq_, 0.6,
- malloc, realloc, free);
+ tor_reallocarray_, tor_free_)
/** Write the body of <b>md</b> into <b>f</b>, with appropriate annotations.
* On success, return the total number of bytes written, and set
}
HT_PROTOTYPE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq);
-HT_GENERATE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq,
- 0.6, malloc, realloc, free);
+HT_GENERATE2(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq,
+ 0.6, tor_reallocarray_, tor_free_)
/** The global nodelist. */
static nodelist_t *the_nodelist=NULL;
HT_PROTOTYPE(policy_map, policy_map_ent_t, node, policy_hash,
policy_eq)
-HT_GENERATE(policy_map, policy_map_ent_t, node, policy_hash,
- policy_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(policy_map, policy_map_ent_t, node, policy_hash,
+ policy_eq, 0.6, tor_reallocarray_, tor_free_)
/** Given a pointer to an addr_policy_t, return a copy of the pointer to the
* "canonical" copy of that addr_policy_t; the canonical copy is a single
HT_PROTOTYPE(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
bidi_map_ent_eq);
-HT_GENERATE(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
- bidi_map_ent_eq, 0.6, malloc, realloc, free);
+HT_GENERATE2(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
+ bidi_map_ent_eq, 0.6, tor_reallocarray_, tor_free_)
/* DOCDOC bidi_map_free */
static void