diff options
| -rw-r--r-- | include/BH/Common.h | 3 | ||||
| -rw-r--r-- | src/Hashmap.c | 10 | ||||
| -rw-r--r-- | src/Queue.c | 10 | ||||
| -rw-r--r-- | test/src/TestCommon.c | 54 |
4 files changed, 67 insertions, 10 deletions
diff --git a/include/BH/Common.h b/include/BH/Common.h index e0e0263..c50397a 100644 --- a/include/BH/Common.h +++ b/include/BH/Common.h @@ -20,6 +20,9 @@ #define BH_PTR2INT(x) ((intptr_t)(x)) #define BH_INT2PTR(x) ((void*)((intptr_t)(x))) +#define BH_CHECK_UADD_WRAP(x, y, type) ((type)((x) + (y)) < (type)(y)) +#define BH_CHECK_USUB_WRAP(x, y, type) ((type)((x) - (y)) > (type)(x)) +#define BH_CHECK_UMUL_WRAP(x, y, type) ((x) > ((type)-1 / (y))) typedef int (*BH_EqualCallback)(const void *, const void *); typedef size_t (*BH_HashCallback)(const void *); diff --git a/src/Hashmap.c b/src/Hashmap.c index 8253ec6..8ecadf8 100644 --- a/src/Hashmap.c +++ b/src/Hashmap.c @@ -62,16 +62,16 @@ static int BH_CalcCapacity(size_t size, *threshold = *capacity * factor; while (size > *threshold) { - *capacity *= 2; - *threshold = *capacity * factor; - /* Catch capacity overflow */ - if (*capacity < 16) + if (BH_CHECK_UMUL_WRAP(*capacity, 2, size_t)) return BH_OOM; + + *capacity *= 2; + *threshold = *capacity * factor; } /* Catch malloc overflow */ - if (*capacity >= ((size_t)-1) / sizeof(BH_HashmapNode)) + if (BH_CHECK_UMUL_WRAP(*capacity, sizeof(BH_HashmapNode), size_t)) return BH_OOM; return BH_OK; diff --git a/src/Queue.c b/src/Queue.c index 4b9d06e..746e8bf 100644 --- a/src/Queue.c +++ b/src/Queue.c @@ -27,7 +27,7 @@ static void BH_QueueDestroy(BH_Queue *queue) static void BH_QueueCopy(BH_Queue *dest, - BH_Queue *src) + BH_Queue *src) { void *iter; @@ -69,7 +69,7 @@ void BH_QueueClear(BH_Queue *queue) int BH_QueueReserve(BH_Queue *queue, - size_t size) + size_t size) { BH_Queue other; @@ -78,7 +78,7 @@ int BH_QueueReserve(BH_Queue *queue, size = queue->size; /* Catch malloc overflow */ - if (size >= ((size_t)-1) / sizeof(void *)) + if (BH_CHECK_UMUL_WRAP(size, sizeof(void *), size_t)) return BH_OOM; /* Prevent same size memory reallocation */ @@ -110,7 +110,7 @@ int BH_QueueReserve(BH_Queue *queue, int BH_QueueInsert(BH_Queue *queue, - void *value) + void *value) { /* Check if queue can contain new element */ if (queue->size + 1 > queue->capacity) @@ -177,7 +177,7 @@ size_t BH_QueueCapacity(BH_Queue *queue) void *BH_QueueIterNext(BH_Queue *queue, - void *iter) + void *iter) { void **element = (void **)iter; diff --git a/test/src/TestCommon.c b/test/src/TestCommon.c new file mode 100644 index 0000000..43249f5 --- /dev/null +++ b/test/src/TestCommon.c @@ -0,0 +1,54 @@ +#include <BH/Unit.h> +#include <BH/Common.h> + + +BH_UNIT_TEST(UADD) +{ + BH_VERIFY(!BH_CHECK_UADD_WRAP(100, 100, uint8_t)); + BH_VERIFY(!BH_CHECK_UADD_WRAP(0, 0, uint8_t)); + BH_VERIFY(BH_CHECK_UADD_WRAP(200, 100, uint8_t)); + BH_VERIFY(BH_CHECK_UADD_WRAP(100, 200, uint8_t)); + BH_VERIFY(BH_CHECK_UADD_WRAP(255, 1, uint8_t)); + BH_VERIFY(BH_CHECK_UADD_WRAP(1, 255, uint8_t)); + + return 0; +} + + +BH_UNIT_TEST(USUB) +{ + BH_VERIFY(!BH_CHECK_USUB_WRAP(100, 100, uint8_t)); + BH_VERIFY(!BH_CHECK_USUB_WRAP(0, 0, uint8_t)); + BH_VERIFY(!BH_CHECK_USUB_WRAP(200, 100, uint8_t)); + BH_VERIFY(BH_CHECK_USUB_WRAP(100, 200, uint8_t)); + BH_VERIFY(!BH_CHECK_USUB_WRAP(255, 1, uint8_t)); + BH_VERIFY(BH_CHECK_USUB_WRAP(1, 255, uint8_t)); + + return 0; +} + + +BH_UNIT_TEST(UMUL) +{ + BH_VERIFY(!BH_CHECK_UMUL_WRAP(0, 2, uint8_t)); + BH_VERIFY(!BH_CHECK_UMUL_WRAP(100, 2, uint8_t)); + BH_VERIFY(BH_CHECK_UMUL_WRAP(200, 100, uint8_t)); + BH_VERIFY(BH_CHECK_UMUL_WRAP(100, 200, uint8_t)); + BH_VERIFY(!BH_CHECK_UMUL_WRAP(255, 1, uint8_t)); + BH_VERIFY(!BH_CHECK_UMUL_WRAP(1, 255, uint8_t)); + + return 0; +} + + +int main(int argc, char **argv) +{ + BH_UNUSED(argc); + BH_UNUSED(argv); + + BH_UNIT_ADD(UADD); + BH_UNIT_ADD(USUB); + BH_UNIT_ADD(UMUL); + + return BH_UnitRun(); +} |
