LibWeb: Saturate CSSPixels unary negation at the i32 minimum

Problem: UBSan crash when computing layout for an element with a giant
negative inset.

Cause: CSSPixels::operator-() returned from_raw(-raw_value()), and
negating the i32 minimum overflows int.

Fix: Negate with saturating_sub(0, raw_value()) — matching the
saturating arithmetic already used by the other CSSPixels operators.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9997
This commit is contained in:
sideshowbarker 2026-06-21 18:22:37 +09:00 committed by Jelle Raaijmakers
parent 86f75e1e35
commit 9402a6e4e1
3 changed files with 21 additions and 1 deletions

View file

@ -180,7 +180,7 @@ public:
}
constexpr CSSPixels operator+() const { return from_raw(+raw_value()); }
constexpr CSSPixels operator-() const { return from_raw(-raw_value()); }
constexpr CSSPixels operator-() const { return from_raw(saturating_sub(0, raw_value())); }
constexpr CSSPixels operator+(CSSPixels const& other) const
{

View file

@ -0,0 +1 @@
PASS (didn't crash)

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<script src="include.js"></script>
<style>
/* A huge negative inset saturates the CSSPixels raw value to the i32 minimum. */
#target {
position: relative;
right: -999999999999999999999999999999999999px;
width: 1px;
height: 1px;
}
</style>
<div id="target"></div>
<script>
test(() => {
// Forces layout, which negates the inset while resolving relative positioning.
document.documentElement.offsetHeight;
println("PASS (didn't crash)");
});
</script>