From 65c61e50306619373e25d0ec344045f973c9022b Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Wed, 27 May 2015 10:54:38 +0200 Subject: [PATCH] util: Add macro to overflow check integer assignments Add a macro that will allow to simplify overflow checks and make them more universal in case data types change. --- src/util/virutil.h | 11 +++++++++++ tests/utiltest.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/util/virutil.h b/src/util/virutil.h index c78b357b43..53025f7086 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -247,4 +247,15 @@ unsigned long long virMemoryLimitTruncate(unsigned long long value); bool virMemoryLimitIsSet(unsigned long long value); unsigned long long virMemoryMaxValue(bool ulong); +/** + * VIR_ASSIGN_IS_OVERFLOW: + * @rvalue: value that is checked (evaluated twice) + * @lvalue: value that the check is against (used in typeof()) + * + * This macro assigns @lvalue to @rvalue and evaluates as true if the value of + * @rvalue did not fit into the @lvalue. + */ +# define VIR_ASSIGN_IS_OVERFLOW(lvalue, rvalue) \ + (((lvalue) = (rvalue)) != (rvalue)) + #endif /* __VIR_UTIL_H__ */ diff --git a/tests/utiltest.c b/tests/utiltest.c index dfa4290caf..3a1f8ebbe9 100644 --- a/tests/utiltest.c +++ b/tests/utiltest.c @@ -172,6 +172,35 @@ testRoundValueToPowerOfTwo(const void *data ATTRIBUTE_UNUSED) } +#define TEST_OVERFLOW(var, val, expect) \ + tmp = val; \ + if (VIR_ASSIGN_IS_OVERFLOW(var, tmp) != expect) { \ + fprintf(stderr, "\noverflow check failed: " \ + "var: " #var " val: " #val "\n"); \ + return -1; \ + } + +static int +testOverflowCheckMacro(const void *data ATTRIBUTE_UNUSED) +{ + long long tmp; + unsigned char luchar; + char lchar; + + TEST_OVERFLOW(luchar, 254, false); + TEST_OVERFLOW(luchar, 255, false); + TEST_OVERFLOW(luchar, 256, true); + TEST_OVERFLOW(luchar, 767, true); + + TEST_OVERFLOW(lchar, 127, false); + TEST_OVERFLOW(lchar, -128, false); + TEST_OVERFLOW(lchar, -129, true); + TEST_OVERFLOW(lchar, 128, true); + + return 0; +} + + static int @@ -193,6 +222,7 @@ mymain(void) DO_TEST(DiskNameToIndex); DO_TEST(ParseVersionString); DO_TEST(RoundValueToPowerOfTwo); + DO_TEST(OverflowCheckMacro); return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }