From bbd8a218a5bdf077fe82f958e3cc583d0131b687 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Wed, 19 Jun 2024 22:04:45 -0500 Subject: [PATCH] AK: Prevent overflow of the min when clamping unsigned values to signed Also, add some tests for the cases that were broken before. --- AK/Math.h | 14 ++++++++++---- Tests/AK/TestIntegerMath.cpp | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/AK/Math.h b/AK/Math.h index 77932d4edef..1a354a7488e 100644 --- a/AK/Math.h +++ b/AK/Math.h @@ -1008,11 +1008,17 @@ constexpr T pow(T x, T y) template constexpr I clamp_to(T value) { - if (value >= static_cast(NumericLimits::max())) - return NumericLimits::max(); + constexpr auto max = static_cast(NumericLimits::max()); + if constexpr (max > 0) { + if (value >= static_cast(NumericLimits::max())) + return NumericLimits::max(); + } - if (value <= static_cast(NumericLimits::min())) - return NumericLimits::min(); + constexpr auto min = static_cast(NumericLimits::min()); + if constexpr (min <= 0) { + if (value <= static_cast(NumericLimits::min())) + return NumericLimits::min(); + } if constexpr (IsFloatingPoint) return round_to(value); diff --git a/Tests/AK/TestIntegerMath.cpp b/Tests/AK/TestIntegerMath.cpp index fc914b15a71..26efd83441e 100644 --- a/Tests/AK/TestIntegerMath.cpp +++ b/Tests/AK/TestIntegerMath.cpp @@ -119,9 +119,11 @@ TEST_CASE(ceil_log2) TEST_CASE(clamp_to) { + EXPECT_EQ((AK::clamp_to(1000000u)), 1000000); EXPECT_EQ((AK::clamp_to(NumericLimits::max())), NumericLimits::max()); EXPECT_EQ((AK::clamp_to(-10)), 0u); + EXPECT_EQ((AK::clamp_to(10)), 10u); EXPECT_EQ((AK::clamp_to(NumericLimits::min())), NumericLimits::min()); EXPECT_EQ((AK::clamp_to(NumericLimits::max())), NumericLimits::max());