From 7b0bb820bb27d298eb4abec3ff4b09e7b6b299e7 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Wed, 25 Oct 2017 09:44:59 +0100 Subject: add checked_sub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I440cd18c249f38194cfd3dfd4a1fc4b7f80858d6 Reviewed-on: https://gerrit.libreoffice.org/43810 Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- include/o3tl/safeint.hxx | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'include') diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx index 1c8bf280171e..8b735fe2edfa 100644 --- a/include/o3tl/safeint.hxx +++ b/include/o3tl/safeint.hxx @@ -68,6 +68,11 @@ template inline bool checked_add(T a, T b, T& result) return !msl::utilities::SafeAdd(a, b, result); } +template inline bool checked_sub(T a, T b, T& result) +{ + return !msl::utilities::SafeSubtract(a, b, result); +} + #elif (defined __GNUC__ && __GNUC__ >= 5) || (__has_builtin(__builtin_mul_overflow) && !(defined ANDROID && defined __clang__)) template inline bool checked_multiply(T a, T b, T& result) @@ -80,6 +85,11 @@ template inline bool checked_add(T a, T b, T& result) return __builtin_add_overflow(a, b, &result); } +template inline bool checked_sub(T a, T b, T& result) +{ + return __builtin_sub_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 @@ -149,6 +159,31 @@ template inline typename std::enable_if::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 inline typename std::enable_if::value, bool>::type checked_sub(T a, T b, T& result) +{ + if ((b > 0 && a < std::numeric_limits::min() + b) || + (b < 0 && a > std::numeric_limits::max() + 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 inline typename std::enable_if::value, bool>::type checked_sub(T a, T b, T& result) +{ + if (a < b) { + return true; + } + + result = a - b; + + return false; +} + #endif } -- cgit