diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-10-24 15:17:49 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-10-25 09:54:14 +0200 |
commit | 9cfb27ae6cb94f0a853ff70e9ad9f3109d305a94 (patch) | |
tree | e97affab079328e786756889ff90b2ff4da4b25c | |
parent | ce3e0b25f5c8cb49fb7ee0b2c2a3c80ace5e4eed (diff) |
add checked_add
Change-Id: I10cba898bba528f5f1bfbd583e27a6821c789ab9
Reviewed-on: https://gerrit.libreoffice.org/43779
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | include/o3tl/safeint.hxx | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx index 4ab31b13ec8f..1c8bf280171e 100644 --- a/include/o3tl/safeint.hxx +++ b/include/o3tl/safeint.hxx @@ -63,6 +63,11 @@ template<typename T> inline bool checked_multiply(T a, T b, T& result) return !msl::utilities::SafeMultiply(a, b, result); } +template<typename T> inline bool checked_add(T a, T b, T& result) +{ + return !msl::utilities::SafeAdd(a, b, result); +} + #elif (defined __GNUC__ && __GNUC__ >= 5) || (__has_builtin(__builtin_mul_overflow) && !(defined ANDROID && defined __clang__)) template<typename T> inline bool checked_multiply(T a, T b, T& result) @@ -70,6 +75,11 @@ template<typename T> inline bool checked_multiply(T a, T b, T& result) return __builtin_mul_overflow(a, b, &result); } +template<typename T> inline bool checked_add(T a, T b, T& result) +{ + return __builtin_add_overflow(a, b, &result); +} + #else //https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow @@ -114,6 +124,31 @@ template<typename T> inline typename std::enable_if<std::is_unsigned<T>::value, return false; } +//https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow +template<typename T> inline typename std::enable_if<std::is_signed<T>::value, bool>::type checked_add(T a, T b, T& result) +{ + if (((b > 0) && (a > (std::numeric_limits<T>::max() - b))) || + ((b < 0) && (a < (std::numeric_limits<T>::min() - b)))) { + return true; + } + + result = a + b; + + return false; +} + +//https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap +template<typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type checked_add(T a, T b, T& result) +{ + if (std::numeric_limits<T>::max() - a < b) { + return true;/* Handle error */ + } + + result = a + b; + + return false; +} + #endif } |