From: Phil Carmody Date: Fri, 14 Nov 2014 22:06:09 +0000 (+0200) Subject: lib: array/hash - protect macro parameters X-Git-Tag: 2.2.16.rc1~217 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcb19f9e9933ef693fe98d3925ea52887ea8cd86;p=thirdparty%2Fdovecot%2Fcore.git lib: array/hash - protect macro parameters If a pointer parameter p is ``ptr + offset'', then sizeof(*p) becomes sizeof(*ptr + offset), which isn't what was wanted. sizeof(*(p)) is the safe expression to use instead. Ditto for just ``*data'' in array.h. The macros in hash.h which have been changed have been reindented for better readability and consistency. The bracketting of elem in (elem)++ in both of the array_foreach* macros isn't actually useful, as elem participates in token-pasting elsewhere. However, the two macros have been made more similar to each other for better parallelism. Signed-off-by: Phil Carmody --- diff --git a/src/lib/array.h b/src/lib/array.h index 80e9bd6fce..09e054339a 100644 --- a/src/lib/array.h +++ b/src/lib/array.h @@ -46,7 +46,7 @@ (typeof(*(array)->v_modifiable)) # define ARRAY_TYPE_CHECK(array, data) \ COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \ - **(array)->v_modifiable, *data) + **(array)->v_modifiable, *(data)) #else # define ARRAY_TYPE_CAST_CONST(array) # define ARRAY_TYPE_CAST_MODIFIABLE(array) @@ -64,7 +64,7 @@ (const char *)(elem = ARRAY_TYPE_CAST_MODIFIABLE(array) \ buffer_get_modifiable_data((array)->arr.buffer, NULL)) + \ (array)->arr.buffer->used; \ - elem != elem ## _end; elem++) + elem != elem ## _end; (elem)++) #else # define array_foreach(array, elem) \ for (elem = *(array)->v; \ diff --git a/src/lib/hash.h b/src/lib/hash.h index d4aa4e4279..b470cb666e 100644 --- a/src/lib/hash.h +++ b/src/lib/hash.h @@ -85,11 +85,14 @@ bool hash_table_lookup_full(const struct hash_table *table, #ifndef __cplusplus # define hash_table_lookup_full(table, lookup_key, orig_key_r, value_r) \ hash_table_lookup_full((table)._table, \ - (void *)((const char *)(lookup_key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, lookup_key)), \ - (void *)((orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, orig_key_r) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*orig_key_r) != sizeof(void *))), \ - (void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *)))) + (void *)((const char *)(lookup_key) + \ + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, lookup_key)), \ + (void *)((orig_key_r) + \ + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, orig_key_r) + \ + COMPILE_ERROR_IF_TRUE(sizeof(*(orig_key_r)) != sizeof(void *))), \ + (void *)((value_r) + \ + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ + COMPILE_ERROR_IF_TRUE(sizeof(*(value_r)) != sizeof(void *)))) #else /* C++ requires (void **) casting, but that's not possible with strict aliasing, so .. we'll just disable the type checks */ @@ -134,9 +137,10 @@ bool hash_table_iterate(struct hash_iterate_context *ctx, #ifndef __cplusplus # define hash_table_iterate(ctx, table, key_r, value_r) \ hash_table_iterate(ctx, \ - (void *)((key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, key_r) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*key_r) != sizeof(void *)) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *))), \ + (void *)((key_r) + \ + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, key_r) + \ + COMPILE_ERROR_IF_TRUE(sizeof(*(key_r)) != sizeof(void *)) + \ + COMPILE_ERROR_IF_TRUE(sizeof(*(value_r)) != sizeof(void *))), \ (void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r))) #else /* C++ requires (void **) casting, but that's not possible with strict