From: Zbigniew Jędrzejewski-Szmek Date: Thu, 12 May 2022 14:29:48 +0000 (+0200) Subject: Add saturate_add() that generalizes size_add() X-Git-Tag: v251-rc3~8^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8b0c43475a764080299f1d69efc2cef0db7b6c66;p=thirdparty%2Fsystemd.git Add saturate_add() that generalizes size_add() --- diff --git a/src/basic/macro.h b/src/basic/macro.h index 3bf982803d5..e6f89608f49 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -457,8 +457,15 @@ static inline int __coverity_check_and_return__(int condition) { _copy; \ }) +#define saturate_add(x, y, limit) \ + ({ \ + typeof(limit) _x = (x); \ + typeof(limit) _y = (y); \ + _x > (limit) || _y >= (limit) - _x ? (limit) : _x + _y; \ + }) + static inline size_t size_add(size_t x, size_t y) { - return y >= SIZE_MAX - x ? SIZE_MAX : x + y; + return saturate_add(x, y, SIZE_MAX); } typedef struct { diff --git a/src/test/test-macro.c b/src/test/test-macro.c index ba319953cd8..c39f64b385e 100644 --- a/src/test/test-macro.c +++ b/src/test/test-macro.c @@ -6,6 +6,15 @@ #include "macro.h" #include "tests.h" +TEST(saturate_add) { + assert_se(saturate_add(1, 2, UINT8_MAX) == 3); + assert_se(saturate_add(1, UINT8_MAX-2, UINT8_MAX) == UINT8_MAX-1); + assert_se(saturate_add(1, UINT8_MAX-1, UINT8_MAX) == UINT8_MAX); + assert_se(saturate_add(1, UINT8_MAX, UINT8_MAX) == UINT8_MAX); + assert_se(saturate_add(2, UINT8_MAX, UINT8_MAX) == UINT8_MAX); + assert_se(saturate_add(60, 60, 50) == 50); +} + TEST(align_power2) { unsigned long i, p2;