summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <stephan.bergmann@allotropia.de>2024-11-16 16:20:29 +0100
committerStephan Bergmann <stephan.bergmann@allotropia.de>2024-11-16 23:27:39 +0100
commit39f701d540d9bc7e90fa99393c2eac165e71faae (patch)
tree3138797f5535a3c60f80c29f2146d06031257e62
parent2b8394b36bf1602ca3f33a00dacd18329cc91d2d (diff)
Avoid UBSan when negating the most negative sal_Int64 value
...as exhibited by recently added 08e566f0c97fb6cc2ee17813e81c221a8d7154c0 "add a couple of tests for tools::BigInt" Change-Id: Icd1080f86ccd985868fce34d6f86e2706acd58df Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176677 Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de> Tested-by: Jenkins
-rw-r--r--include/tools/bigint.hxx8
-rw-r--r--tools/source/generic/bigint.cxx5
2 files changed, 8 insertions, 5 deletions
diff --git a/include/tools/bigint.hxx b/include/tools/bigint.hxx
index 2b7d9870d3e3..2f5fd46ec26d 100644
--- a/include/tools/bigint.hxx
+++ b/include/tools/bigint.hxx
@@ -164,10 +164,10 @@ inline BigInt::operator sal_Int64() const
case 1:
return bIsNeg ? -sal_Int64(nNum[0]) : nNum[0];
case 2:
- if (sal_uInt64 n = (sal_uInt64(nNum[1]) << 32) + nNum[0]; bIsNeg && n <= maxForNegInt64)
- return -sal_Int64(n); // maxForNegInt64 will convert correctly
- else if (!bIsNeg && n <= maxForPosInt64)
- return n;
+ if (sal_uInt64 n = (sal_uInt64(nNum[1]) << 32) + nNum[0]; bIsNeg && n < maxForNegInt64)
+ return -sal_Int64(n);
+ else if ((bIsNeg && n == maxForNegInt64) || (!bIsNeg && n <= maxForPosInt64))
+ return n; // maxForNegInt64 will convert correctly
}
assert(false && "out of range");
return 0;
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
index 2c705e30c755..2f56ee28416d 100644
--- a/tools/source/generic/bigint.cxx
+++ b/tools/source/generic/bigint.cxx
@@ -25,6 +25,7 @@
#include <algorithm>
#include <cmath>
#include <cstring>
+#include <limits>
#include <span>
/**
@@ -461,7 +462,9 @@ BigInt::BigInt( sal_Int64 nValue )
}
else
{
- for (sal_uInt64 n = static_cast<sal_uInt64>(bIsNeg ? -nValue : nValue); n != 0; n >>= 32)
+ for (sal_uInt64 n = static_cast<sal_uInt64>(
+ (bIsNeg && nValue != std::numeric_limits<sal_Int64>::min()) ? -nValue : nValue);
+ n != 0; n >>= 32)
nNum[nLen++] = static_cast<sal_uInt32>(n);
}
}