]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add saturate_add() that generalizes size_add()
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 12 May 2022 14:29:48 +0000 (16:29 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 12 May 2022 15:15:51 +0000 (17:15 +0200)
src/basic/macro.h
src/test/test-macro.c

index 3bf982803d525ffd5c9ba8098e600b63f5dc7bfb..e6f89608f49ee2b0c9ccbc70200169cea41a85b0 100644 (file)
@@ -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 {
index ba319953cd86c83f5c854b7aedb1f4b864b239ed..c39f64b385edfb7995e05fd1c219b9ccd71f524a 100644 (file)
@@ -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;