[Libreoffice-commits] core.git: 2 commits - extensions/source include/o3tl oox/source vcl/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Wed Aug 25 15:12:49 UTC 2021


 extensions/source/propctrlr/standardcontrol.cxx |    4 +---
 include/o3tl/float_int_conversion.hxx           |   18 ++++++++++++++++--
 oox/source/vml/vmlformatting.cxx                |    9 +--------
 vcl/source/window/scrwnd.cxx                    |   15 ++-------------
 vcl/source/window/window2.cxx                   |    7 +------
 5 files changed, 21 insertions(+), 32 deletions(-)

New commits:
commit 2cdcf5805b32098e75285015b57bf0f890723e41
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed Aug 25 10:20:48 2021 +0200
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Wed Aug 25 17:12:28 2021 +0200

    Use o3tl::saturating_cast here
    
    These were of type long previously, with corresponding limits of
    LONG_MIN/MAX; in commit 3aef606f2758172a27718a06fea0ff9080e4d80f,
    they were changed to tools::Long, but without adapting limits
    accordingly.
    
    This adapts the limits to std::numeric_limits<tools::Long>::min()/max().
    
    Change-Id: Ief4ee0a6219c837e1d971273da698ab07fa8a1e4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120984
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/vcl/source/window/scrwnd.cxx b/vcl/source/window/scrwnd.cxx
index 7be0cd6074cf..21bbb7f787de 100644
--- a/vcl/source/window/scrwnd.cxx
+++ b/vcl/source/window/scrwnd.cxx
@@ -217,19 +217,8 @@ void ImplWheelWindow::ImplRecalcScrollValues()
             double fValX = static_cast<double>(mnActDeltaX) * nMult;
             double fValY = static_cast<double>(mnActDeltaY) * nMult;
 
-            if( !o3tl::convertsToAtMost(fValX, LONG_MAX) )
-                mnActDeltaX = LONG_MAX;
-            else if( !o3tl::convertsToAtLeast(fValX, LONG_MIN) )
-                mnActDeltaX = LONG_MIN;
-            else
-                mnActDeltaX = static_cast<tools::Long>(fValX);
-
-            if( !o3tl::convertsToAtMost(fValY, LONG_MAX) )
-                mnActDeltaY = LONG_MAX;
-            else if( !o3tl::convertsToAtLeast(fValY, LONG_MIN) )
-                mnActDeltaY = LONG_MIN;
-            else
-                mnActDeltaY = static_cast<tools::Long>(fValY);
+            mnActDeltaX = o3tl::saturating_cast<tools::Long>(fValX);
+            mnActDeltaY = o3tl::saturating_cast<tools::Long>(fValY);
         }
     }
 }
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index 1db7b7aaf280..dd3a5fe05b28 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -588,12 +588,7 @@ static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiply
 
         const double fVal = nNewPos - nN;
 
-        if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN) )
-            nNewPos = LONG_MIN;
-        else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX) )
-            nNewPos = LONG_MAX;
-        else
-            nNewPos = static_cast<tools::Long>(fVal);
+        nNewPos = o3tl::saturating_cast<tools::Long>(fVal);
     }
 
     pScrl->DoScroll( nNewPos );
commit e9ab5a5e4e725a348a4276b72fda63cdac2a131c
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Tue Aug 24 15:58:15 2021 +0200
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Wed Aug 25 17:12:14 2021 +0200

    Introduce o3tl::saturating_cast for floating-point->integer conversion
    
    Change-Id: I73191e5ab25fdd9fd8a788db9858b5eb9d3ab955
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120885
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/extensions/source/propctrlr/standardcontrol.cxx b/extensions/source/propctrlr/standardcontrol.cxx
index 584c66889348..8c33d0598711 100644
--- a/extensions/source/propctrlr/standardcontrol.cxx
+++ b/extensions/source/propctrlr/standardcontrol.cxx
@@ -235,9 +235,7 @@ namespace pcr
         for ( sal_uInt16 d = 0; d < nDigits; ++d )
             n *= 10;
 
-        if ( !o3tl::convertsToAtMost(n, std::numeric_limits<int>::max()) )
-            return std::numeric_limits<int>::max();
-        return static_cast<int>(n);
+        return o3tl::saturating_cast<int>(n);
     }
 
     static double ImplCalcDoubleValue( int nValue, sal_uInt16 nDigits )
diff --git a/include/o3tl/float_int_conversion.hxx b/include/o3tl/float_int_conversion.hxx
index dfaea5ce3bd2..36bce97dd742 100644
--- a/include/o3tl/float_int_conversion.hxx
+++ b/include/o3tl/float_int_conversion.hxx
@@ -20,7 +20,7 @@ namespace o3tl
 // Return true iff `value` of floating-point type `F` converts to a value of integral type `I` no
 // smaller than `min`:
 template <typename F, typename I>
-std::enable_if_t<std::is_floating_point_v<F> && std::is_integral_v<I>, bool>
+constexpr std::enable_if_t<std::is_floating_point_v<F> && std::is_integral_v<I>, bool>
 convertsToAtLeast(F value, I min)
 {
     // If `F(min)`, `F(min) - F(1)` are too large in magnitude for `F`'s precision, then they either
@@ -33,7 +33,7 @@ convertsToAtLeast(F value, I min)
 // Return true iff `value` of floating-point type `F` converts to a value of integral type `I` no
 // larger than `max`:
 template <typename F, typename I>
-std::enable_if_t<std::is_floating_point_v<F> && std::is_integral_v<I>, bool>
+constexpr std::enable_if_t<std::is_floating_point_v<F> && std::is_integral_v<I>, bool>
 convertsToAtMost(F value, I max)
 {
     // If `F(max)`, `F(max) + F(1)` are too large in magnitude for `F`'s precision, then they either
@@ -43,6 +43,20 @@ convertsToAtMost(F value, I max)
     return value < F(max) + F(1);
 }
 
+// Casts a floating-point to an integer, avoiding overflow. Used like:
+//     sal_Int64 n = o3tl::saturating_cast<sal_Int64>(f);
+template <typename I, typename F>
+constexpr std::enable_if_t<std::is_floating_point_v<F> && std::is_integral_v<I>, I>
+saturating_cast(F f)
+{
+    if constexpr (std::is_signed_v<I>)
+        if (!convertsToAtLeast(f, std::numeric_limits<I>::min()))
+            return std::numeric_limits<I>::min();
+    if (!convertsToAtMost(f, std::numeric_limits<I>::max()))
+        return std::numeric_limits<I>::max();
+    return f;
+}
+
 // Return `value` of floating-point type `F` rounded to the nearest integer away from zero (which
 // can be useful in calls to convertsToAtLeast/Most(roundAway(x), n), to reject x that are
 // smaller/larger than n because they have a fractional part):
diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx
index b7dc37b5e940..ef7e692838fe 100644
--- a/oox/source/vml/vmlformatting.cxx
+++ b/oox/source/vml/vmlformatting.cxx
@@ -201,14 +201,7 @@ sal_Int64 ConversionHelper::decodeMeasureToEmu( const GraphicHelper& rGraphicHel
         OSL_FAIL( "ConversionHelper::decodeMeasureToEmu - unknown measure unit" );
         fValue = nRefValue;
     }
-    fValue += 0.5;
-    if (!o3tl::convertsToAtMost(fValue, std::numeric_limits<sal_Int64>::max())) {
-        return std::numeric_limits<sal_Int64>::max();
-    }
-    if (!o3tl::convertsToAtLeast(fValue, std::numeric_limits<sal_Int64>::min())) {
-        return std::numeric_limits<sal_Int64>::min();
-    }
-    return static_cast< sal_Int64 >( fValue );
+    return o3tl::saturating_cast< sal_Int64 >( fValue + 0.5 );
 }
 
 sal_Int32 ConversionHelper::decodeMeasureToHmm( const GraphicHelper& rGraphicHelper,


More information about the Libreoffice-commits mailing list