include/tools/bigint.hxx        |    8 ++++----
 tools/source/generic/bigint.cxx |    5 ++++-
 2 files changed, 8 insertions(+), 5 deletions(-)

New commits:
commit 39f701d540d9bc7e90fa99393c2eac165e71faae
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Sat Nov 16 16:20:29 2024 +0100
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Sat Nov 16 23:27:39 2024 +0100

    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.bergm...@allotropia.de>
    Tested-by: Jenkins

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);
     }
 }

Reply via email to