Fix incorrect tokenization of non-exponential numbers ending with "E" (#49280)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49280

We were incorrectly consuming an `E` at the end of number tokens, even if not followed by a digit, which breaks dimension tokens where the unit starts with "E", like `em`. Follow the spec the right way:

https://www.w3.org/TR/css-syntax-3/#consume-number

> If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E (e), optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+), followed by a digit, then...

Changelog: [Internal]

Reviewed By: joevilches

Differential Revision: D69330975

fbshipit-source-id: a9bd5bceac9efbf02c1b7fb60659093774bb7228
This commit is contained in:
Nick Gerleman
2025-02-07 18:14:42 -08:00
committed by Facebook GitHub Bot
parent f40d69f06d
commit 8bd01c7d01
3 changed files with 13 additions and 1 deletions
@@ -163,7 +163,9 @@ class CSSTokenizer {
int32_t exponentSign = 1.0;
int32_t exponentPart = 0;
if (peek() == 'e' || peek() == 'E') {
if ((peek() == 'e' || peek() == 'E') &&
(isDigit(peek(1)) ||
((peek(1) == '+' || peek(1) == '-') && isDigit(peek(2))))) {
advance();
if (peek() == '+' || peek() == '-') {
if (peek() == '-') {
@@ -44,6 +44,11 @@ TEST(CSSLength, length_values) {
auto pctValue = parseCSSProperty<CSSLength>("-40%");
EXPECT_TRUE(std::holds_alternative<std::monostate>(pctValue));
auto negativeValue = parseCSSProperty<CSSLength>("-20em");
EXPECT_TRUE(std::holds_alternative<CSSLength>(negativeValue));
EXPECT_EQ(std::get<CSSLength>(negativeValue).value, -20.0f);
EXPECT_EQ(std::get<CSSLength>(negativeValue).unit, CSSLengthUnit::Em);
}
TEST(CSSLength, parse_constexpr) {
@@ -112,6 +112,11 @@ TEST(CSSTokenizer, dimension_values) {
".3xyz",
CSSToken{CSSTokenType::Dimension, 0.3, "xyz"},
CSSToken{CSSTokenType::EndOfFile});
EXPECT_TOKENS(
"-0.5em",
CSSToken{CSSTokenType::Dimension, -0.5, "em"},
CSSToken{CSSTokenType::EndOfFile});
}
TEST(CSSTokenizer, percent_values) {