diff options
author | Chad Versace <chad.versace@intel.com> | 2015-01-04 13:36:10 -0800 |
---|---|---|
committer | Chad Versace <chad.versace@intel.com> | 2015-01-27 09:36:05 -0800 |
commit | 463bddf557424f81a8f8af113ed5705868a57eda (patch) | |
tree | 36ef22719d7dc93edc7ca9fa58331e4741fb7360 | |
parent | 5e8b6ed53cdfbf34b610a9f989dd4dd3b9b39e32 (diff) |
core: Add arithmetic functions that detect overflow
Define the function below. All act on size_t inputs.
wcore_add_size
wcore_iadd_size : in-place addition
wcore_mul_size
wcore_imul_size : in-place multiplication
Future patches will use the functions to safely calculate the 'size'
value given to malloc.
Signed-off-by: Chad Versace <chad.versace@intel.com>
Tested-by: Emil Velikov <emil.l.velikov@gmail.com> (msvc/wgl)
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
-rw-r--r-- | src/waffle/core/wcore_util.c | 22 | ||||
-rw-r--r-- | src/waffle/core/wcore_util.h | 27 |
2 files changed, 49 insertions, 0 deletions
diff --git a/src/waffle/core/wcore_util.c b/src/waffle/core/wcore_util.c index b2dafe4..eee064d 100644 --- a/src/waffle/core/wcore_util.c +++ b/src/waffle/core/wcore_util.c @@ -28,6 +28,28 @@ #include "wcore_error.h" #include "wcore_util.h" +bool +wcore_add_size(size_t *res, size_t x, size_t y) +{ + if (x > SIZE_MAX - y) { + return false; + } + + *res = x + y; + return true; +} + +bool +wcore_mul_size(size_t *res, size_t x, size_t y) +{ + if (x > SIZE_MAX / y) { + return false; + } + + *res = x * y; + return true; +} + void* wcore_malloc(size_t size) { diff --git a/src/waffle/core/wcore_util.h b/src/waffle/core/wcore_util.h index d2aaa27..183134f 100644 --- a/src/waffle/core/wcore_util.h +++ b/src/waffle/core/wcore_util.h @@ -26,6 +26,7 @@ #pragma once #include <stddef.h> +#include "c99_compat.h" #define container_of(ptr, type, member) ({ \ const __typeof__(((type *)0)->member ) *__mptr = (ptr); \ @@ -49,6 +50,32 @@ return 0; \ } +/// @brief Addition that detects arithmetic overflow. +/// +/// If the addition would result in overflow, then return false and do not +/// update @a res. +bool +wcore_add_size(size_t *res, size_t x, size_t y); + +/// @brief In-place variant of wcore_add_size(). +static inline bool +wcore_iadd_size(size_t *x, size_t y) { + return wcore_add_size(x, *x, y); +} + +/// @brief Multiplication that detects arithmetic overflow. +/// +/// If the multiplication would result in overflow, then return false and do +/// not update @a res. +bool +wcore_mul_size(size_t *res, size_t x, size_t y); + +/// @brief In-place variant of wcore_mul_size(). +static inline bool +wcore_imul_size(size_t *x, size_t y) { + return wcore_mul_size(x, *x, y); +} + /// @brief Wrapper around malloc() that emits error if allocation fails. void* wcore_malloc(size_t size); |