Merge remote-tracking branch 'public/ticket11737'

This commit is contained in:
Nick Mathewson 2015-01-29 15:09:55 -05:00
commit 5faa017b86
2 changed files with 24 additions and 4 deletions

4
changes/ticket11737 Normal file
View File

@ -0,0 +1,4 @@
o Minor features:
- Prevent bugs from causing infinite loops in our hash-table
iteration code by adding assertions that cached hash values have
not been corrupted. Closes ticket 11737.

View File

@ -121,16 +121,24 @@ ht_string_hash(const char *s)
((void)0) ((void)0)
#endif #endif
#define HT_BUCKET_NUM_(head, field, elm, hashfn) \
(HT_ELT_HASH_(elm,field,hashfn) % head->hth_table_length)
/* Helper: alias for the bucket containing 'elm'. */ /* Helper: alias for the bucket containing 'elm'. */
#define HT_BUCKET_(head, field, elm, hashfn) \ #define HT_BUCKET_(head, field, elm, hashfn) \
((head)->hth_table[HT_ELT_HASH_(elm,field,hashfn) \ ((head)->hth_table[HT_BUCKET_NUM_(head, field, elm, hashfn)])
% head->hth_table_length])
#define HT_FOREACH(x, name, head) \ #define HT_FOREACH(x, name, head) \
for ((x) = HT_START(name, head); \ for ((x) = HT_START(name, head); \
(x) != NULL; \ (x) != NULL; \
(x) = HT_NEXT(name, head, x)) (x) = HT_NEXT(name, head, x))
#ifndef HT_NDEBUG
#define HT_ASSERT_(x) tor_assert(x)
#else
#define HT_ASSERT_(x) (void)0
#endif
#define HT_PROTOTYPE(name, type, field, hashfn, eqfn) \ #define HT_PROTOTYPE(name, type, field, hashfn, eqfn) \
int name##_HT_GROW(struct name *ht, unsigned min_capacity); \ int name##_HT_GROW(struct name *ht, unsigned min_capacity); \
void name##_HT_CLEAR(struct name *ht); \ void name##_HT_CLEAR(struct name *ht); \
@ -257,8 +265,11 @@ ht_string_hash(const char *s)
{ \ { \
unsigned b = 0; \ unsigned b = 0; \
while (b < head->hth_table_length) { \ while (b < head->hth_table_length) { \
if (head->hth_table[b]) \ if (head->hth_table[b]) { \
HT_ASSERT_(b == \
HT_BUCKET_NUM_(head,field,head->hth_table[b],hashfn)); \
return &head->hth_table[b]; \ return &head->hth_table[b]; \
} \
++b; \ ++b; \
} \ } \
return NULL; \ return NULL; \
@ -272,13 +283,18 @@ ht_string_hash(const char *s)
name##_HT_NEXT(struct name *head, struct type **elm) \ name##_HT_NEXT(struct name *head, struct type **elm) \
{ \ { \
if ((*elm)->field.hte_next) { \ if ((*elm)->field.hte_next) { \
HT_ASSERT_(HT_BUCKET_NUM_(head,field,*elm,hashfn) == \
HT_BUCKET_NUM_(head,field,(*elm)->field.hte_next,hashfn)); \
return &(*elm)->field.hte_next; \ return &(*elm)->field.hte_next; \
} else { \ } else { \
unsigned b = (HT_ELT_HASH_(*elm, field, hashfn) \ unsigned b = (HT_ELT_HASH_(*elm, field, hashfn) \
% head->hth_table_length)+1; \ % head->hth_table_length)+1; \
while (b < head->hth_table_length) { \ while (b < head->hth_table_length) { \
if (head->hth_table[b]) \ if (head->hth_table[b]) { \
HT_ASSERT_(b == \
HT_BUCKET_NUM_(head,field,head->hth_table[b],hashfn)); \
return &head->hth_table[b]; \ return &head->hth_table[b]; \
} \
++b; \ ++b; \
} \ } \
return NULL; \ return NULL; \