Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: fab4ac5572e0b4160bf6c2bfb5e6ce0855baae14
      
https://github.com/WebKit/WebKit/commit/fab4ac5572e0b4160bf6c2bfb5e6ce0855baae14
  Author: Chris Dumez <[email protected]>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    A 
LayoutTests/imported/w3c/web-platform-tests/css/selectors/nth-child-large-anplusb-clamp-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/css/selectors/nth-child-large-anplusb-clamp.html
    M Source/WebCore/css/parser/CSSSelectorParser.cpp

  Log Message:
  -----------
  :nth-child() An+B coefficients are converted from double to int without 
clamping
https://bugs.webkit.org/show_bug.cgi?id=316962

Reviewed by Darin Adler.

CSSSelectorParser::consumeANPlusB() converted the An+B coefficients from
the token's numericValue() (a double) to int using a static_cast (for the
B term in the NumberToken path) or an implicit narrowing conversion (for
the A term and the trailing B term). numericValue() is computed by the
tokenizer with no magnitude clamping, and numericValueType() == IntegerValueType
only means the literal had no decimal point or exponent -- not that it fits
in an int. A selector such as :nth-child(99999999999999999999n) therefore
fed a ~1e20 double into a double-to-int conversion, which is undefined
behavior when the value is outside the range of int ([conv.fpint]).

In practice the result is architecture-dependent: ARM64's FCVTZS saturates
to INT_MAX, while x86-64's cvttsd2si yields INT_MIN, and a 
-fsanitize=float-cast-overflow
build traps outright.

Fix this by clamping with clampTo<int>() at all three conversion sites, so
huge coefficients deterministically saturate to INT_MAX / INT_MIN on every
architecture. This matches Blink, whose CSSSelectorParser::ConsumeANPlusB
already uses ClampTo<int>(token.NumericValue()) at the corresponding sites
(renderer/core/css/parser/css_selector_parser.cc).

A layout test is added that parses out-of-range coefficients and reads back
the serialized selectorText, asserting the clamped INT_MAX result. The test
passes everywhere with the fix. Without the fix it fails only on architectures
whose double-to-int conversion does not happen to saturate (e.g. x86-64, where
the value wraps to INT_MIN and serializes as "-2147483648n"); on ARM64 the
hardware already saturates to the same value clampTo<int>() produces, so it
cannot fail there. This is noted because the test deliberately validates the
correct result rather than relying on a sanitizer trap.

Test: 
imported/w3c/web-platform-tests/css/selectors/nth-child-large-anplusb-clamp.html

* 
LayoutTests/imported/w3c/web-platform-tests/css/selectors/nth-child-large-anplusb-clamp-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/css/selectors/nth-child-large-anplusb-clamp.html:
 Added.
* Source/WebCore/css/parser/CSSSelectorParser.cpp:
(WebCore::consumeANPlusB):

Canonical link: https://commits.webkit.org/315197@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to