From: Michal Privoznik <[email protected]>

The aim of VIR_MULTIPLY_ADD_IS_OVERFLOW() macro is to check
whether a multiplication and subsequent addition would overflow
over given limit. For instance, if value * multiply + add would
fit into say unsigned long. But because of the way the macro is
written, a compiler warning may be thrown if 'add' is zero, i.e.
we want to check just if value * multiply would overflow.

Rewrite the offending part of the macro to make if work even in
that case.

Signed-off-by: Michal Privoznik <[email protected]>
---
 src/internal.h   | 2 +-
 tests/utiltest.c | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/internal.h b/src/internal.h
index df311551a4..4ba42f330a 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -54,7 +54,7 @@
  */
 #define VIR_MULTIPLY_ADD_IS_OVERFLOW(limit, value, multiply, add) \
   (G_UNLIKELY(((multiply) > 0 && (value) > (limit) / (multiply)) || \
-              ((limit) - ((value) * (multiply)) < (add))))
+              ((limit) - (add) < ((value) * (multiply)))))
 
 /* The library itself is allowed to use deprecated functions /
  * variables, so effectively undefine the deprecated attribute
diff --git a/tests/utiltest.c b/tests/utiltest.c
index 3d3e1a17ec..24d175f67a 100644
--- a/tests/utiltest.c
+++ b/tests/utiltest.c
@@ -452,6 +452,12 @@ testMultiplyAddIsOverflow(const void *data G_GNUC_UNUSED)
         return -1;
     }
 
+    if (VIR_MULTIPLY_ADD_IS_OVERFLOW(ULONG_MAX, a, 1024, 0)) {
+        VIR_TEST_DEBUG("should not have failed (limit=%lu, value=%lu, 
multiply=1024, add=0).",
+                       ULONG_MAX, a);
+        return -1;
+    }
+
     return 0;
 }
 
-- 
2.56.0

Reply via email to