LibWeb: Saturate CSSPixels::abs() at the i32 minimum

Problem: CSSPixels::abs() invokes UB for the i32 minimum raw value.

Cause: abs() returned from_raw(::abs(m_value)) — and ::abs() of the i32
minimum isn’t representable as an int.

Fix: Compute the magnitude with saturating_sub(0, raw_value()) for
negative inputs — so the i32 minimum saturates to the maximum.
This commit is contained in:
sideshowbarker 2026-06-22 08:30:14 +09:00 committed by Jelle Raaijmakers
parent 503453eb9c
commit b024e45c2c
2 changed files with 9 additions and 1 deletions

View file

@ -246,7 +246,7 @@ public:
return *this;
}
constexpr CSSPixels abs() const { return from_raw(::abs(m_value)); }
constexpr CSSPixels abs() const { return raw_value() < 0 ? from_raw(saturating_sub(0, raw_value())) : *this; }
CSSPixels& scale_by(float value)
{

View file

@ -124,6 +124,14 @@ TEST_CASE(saturated_subtraction)
EXPECT_EQ(value - -1, CSSPixels(INFINITY));
}
TEST_CASE(saturated_abs)
{
// abs() of the minimum saturates to the maximum instead of overflowing.
EXPECT_EQ(CSSPixels::min().abs(), CSSPixels::max());
EXPECT_EQ(CSSPixels::from_raw(-5).abs(), CSSPixels::from_raw(5));
EXPECT_EQ(CSSPixels::from_raw(5).abs(), CSSPixels::from_raw(5));
}
TEST_CASE(multiplication_uses_i64_for_raw_values)
{
CSSPixels a(1200);