Prevent overflow in intersection observer area evaluation (#36955)

Prevent overflowing by not calculating the area and reordering
arithmetic operations.

Testing: No regression in wpt tests:
1495105545
Fixes: https://github.com/servo/servo/issues/36940

Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
webbeef 2025-05-10 20:05:47 -07:00 committed by GitHub
parent 6cd44061d7
commit 9c3069366e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -524,11 +524,10 @@ impl IntersectionObserver {
// Step 9
// > Let targetArea be targetRects area.
let target_area = target_rect.size.width.0 * target_rect.size.height.0;
// Step 10
// > Let intersectionArea be intersectionRects area.
let intersection_area = intersection_rect.size.width.0 * intersection_rect.size.height.0;
// These steps are folded in Step 12, rewriting (w1 * h1) / (w2 * h2) as (w1 / w2) * (h1 / h2)
// to avoid multiplication overflows.
// Step 11
// > Let isIntersecting be true if targetRect and rootBounds intersect or are edge-adjacent,
@ -545,9 +544,12 @@ impl IntersectionObserver {
// Step 12
// > If targetArea is non-zero, let intersectionRatio be intersectionArea divided by targetArea.
// > Otherwise, let intersectionRatio be 1 if isIntersecting is true, or 0 if isIntersecting is false.
let intersection_ratio = match target_area {
0 => is_intersecting.into(),
_ => (intersection_area as f64) / (target_area as f64),
let intersection_ratio = if target_rect.size.width.0 == 0 || target_rect.size.height.0 == 0
{
is_intersecting.into()
} else {
(intersection_rect.size.width.0 as f64 / target_rect.size.width.0 as f64) *
(intersection_rect.size.height.0 as f64 / target_rect.size.height.0 as f64)
};
// Step 13