Title: [279498] trunk
Revision
279498
Author
da...@apple.com
Date
2021-07-01 23:37:39 -0700 (Thu, 01 Jul 2021)

Log Message

CSS parser using a token for Unicode ranges, but recent CSS specification says it should not
https://bugs.webkit.org/show_bug.cgi?id=227569

Reviewed by Sam Weinig.

LayoutTests/imported/w3c:

* web-platform-tests/css/css-syntax/unicode-range-selector-expected.txt:
* web-platform-tests/css/css-syntax/urange-parsing-expected.txt:
Expect passes instead of fails.

Source/WebCore:

Tests: imported/w3c/web-platform-tests/css/css-syntax/unicode-range-selector.html
       imported/w3c/web-platform-tests/css/css-syntax/urange-parsing.html

* css/parser/CSSParserToken.cpp:
(WebCore::CSSParserToken::CSSParserToken): Change the NumberToken constructor to
take a StringView so we can recover the original text if we need to parse it as
part of a Unicode range.
(WebCore::mergeIfAdjacent): Added. Helper used by convertToDimensionWithUnit.
(WebCore::CSSParserToken::convertToDimensionWithUnit): If the number token string
is adjacent to the dimension, then store the string containing both, so it can
be used if we need to parse it as part of a Unicode range. If the string is long,
then don't bother because a long string can't be part of such a range anyway. We
use 4 bits for the length, so can handle lengths in the range [1,15].
(WebCore::CSSParserToken::originalText const): Added. Used to recover the original
text for Unicode range parsing.
(WebCore::CSSParserToken::unitString const): Added. Used to get just the unit part
of the string for DimensionToken, since the full string now can include the number
as well in some cases (see above).
(WebCore::CSSParserToken::copyWithUpdatedString const): Changed the argument type
to StringView instead of using const& and added an assertion since this is only
safe if we are moving the backing characters, not changing the string contents.
(WebCore::CSSParserToken::valueDataCharRawEqual const): Deleted.
(WebCore::CSSParserToken::operator== const): Use StringView == operator instead of
our own valueDataCharRawEqual function. Also use unitString for DimensionToken.
(WebCore::CSSParserToken::serialize const): Use unitString for DimensionToken.
* css/parser/CSSParserToken.h: Updated for the above. Also deleted
UnicodeRangeToken, unicodeRangeStart, unicodeRangeEnd, and m_unicodeRange.

* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeResolutionCSSPrimitiveValueWithKnownTokenTypeDimension):
Use unitString for DimensionToken.
(WebCore::CSSPropertyParserHelpers::parseHexColor): Ditto.

* css/parser/CSSPropertyParserWorkerSafe.cpp:
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeOptionalDelimiter): Added.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeIdentifier): Added.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeAndAppendOptionalNumber): Added.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeAndAppendOptionalDelimiter): Added.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeAndAppendOptionalQuestionMarks): Added.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeUnicodeRangeString): Added.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeUnicodeRange): Added. Along with the
functions above, this implements the CSS specification's algorithm for consuming a Unicode
range, based on existing tokens without requiring a <urange> token.
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeFontFaceUnicodeRange): Call
the new consumeUnicodeRange function from this file instead of the old one that
depended on a <urange> token. Also refactored to use auto and to do the validity
check for the range as specified.

* css/parser/CSSSelectorParser.cpp:
(WebCore::consumeANPlusB): Use unitString for DimensionToken.

* css/parser/CSSTokenizer.cpp:
(WebCore::CSSTokenizer::letterU): Deleted.
(WebCore::CSSTokenizer::consumeNumber): Added code to pass in the original text
when constructing a NumberToken.
(WebCore::CSSTokenizer::consumeUnicodeRange): Deleted.

* css/parser/CSSTokenizer.h: Deleted consumeUnicodeRange.

* css/parser/SizesCalcParser.cpp:
(WebCore::SizesCalcParser::calcToReversePolishNotation): Removed case for
UnicodeRangeToken.

* dom/ConstantPropertyMap.cpp:
(WebCore::variableDataForPositivePixelLength): Pass a null StringView for the
original text when constructing a NumberToken. This is OK for now since this token
won't ever be parsed as part of a Unicode range, and we can change it if we ever
need to support originalText for any other cases.
(WebCore::variableDataForPositiveDuration): Ditto.

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (279497 => 279498)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,3 +1,14 @@
+2021-06-30  Darin Adler  <da...@apple.com>
+
+        CSS parser using a token for Unicode ranges, but recent CSS specification says it should not
+        https://bugs.webkit.org/show_bug.cgi?id=227569
+
+        Reviewed by Sam Weinig.
+
+        * web-platform-tests/css/css-syntax/unicode-range-selector-expected.txt:
+        * web-platform-tests/css/css-syntax/urange-parsing-expected.txt:
+        Expect passes instead of fails.
+
 2021-07-01  Alex Christensen  <achristen...@webkit.org>
 
         Align beacon CORS mode with Chrome and Firefox

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/unicode-range-selector-expected.txt (279497 => 279498)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/unicode-range-selector-expected.txt	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/unicode-range-selector-expected.txt	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,3 +1,3 @@
 
-FAIL Unicode range is not a token, and doesn't cause confusion in selectors assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
+PASS Unicode range is not a token, and doesn't cause confusion in selectors
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/urange-parsing-expected.txt (279497 => 279498)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/urange-parsing-expected.txt	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/urange-parsing-expected.txt	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,5 +1,5 @@
 
-FAIL "u/**/+/**/a/**/?" => "U+A0-AF" assert_equals: expected "U+A0-AF" but got "U+1357"
+PASS "u/**/+/**/a/**/?" => "U+A0-AF"
 PASS "u+abc" => "U+ABC"
 PASS "U+abc" => "U+ABC"
 PASS "u+ABC" => "U+ABC"
@@ -27,9 +27,9 @@
 PASS "u+aa?????" is invalid
 PASS "u+a??????" is invalid
 PASS "u+a?a" is invalid
-FAIL "u+aaaaaa" is invalid assert_equals: expected "U+1357" but got "U+AAAAAA"
-FAIL "u+a?????" is invalid assert_equals: expected "U+1357" but got "U+A00000-AFFFFF"
-FAIL "u/**/+0a/**/?" => "U+A0-AF" assert_equals: expected "U+A0-AF" but got "U+1357"
+PASS "u+aaaaaa" is invalid
+PASS "u+a?????" is invalid
+PASS "u/**/+0a/**/?" => "U+A0-AF"
 PASS "u+0a" => "U+A"
 PASS "U+0a0" => "U+A0"
 PASS "u+0aaaaa" => "U+AAAAA"
@@ -44,9 +44,9 @@
 PASS "u+0a????" => "U+A0000-AFFFF"
 PASS "u+0a?????" is invalid
 PASS "u+00a????" is invalid
-FAIL "u+22222a" is invalid assert_equals: expected "U+1357" but got "U+22222A"
+PASS "u+22222a" is invalid
 PASS "u+1e9a" => "U+1E9A"
-FAIL "u/**/+0/**/?" => "U+0-F" assert_equals: expected "U+0-F" but got "U+1357"
+PASS "u/**/+0/**/?" => "U+0-F"
 PASS "u/**/0" is invalid
 PASS "u+0" => "U+0"
 PASS "u+00" => "U+0"
@@ -63,9 +63,9 @@
 PASS "u+0??????" is invalid
 PASS "u+1e3" => "U+1E3"
 PASS "u+1e-20" => "U+1E-20"
-FAIL "u+222222" is invalid assert_equals: expected "U+1357" but got "U+222222"
-FAIL "u+2?????" is invalid assert_equals: expected "U+1357" but got "U+200000-2FFFFF"
-FAIL "u/**/+0/**/-0a" => "U+0-A" assert_equals: expected "U+0-A" but got "U+1357"
+PASS "u+222222" is invalid
+PASS "u+2?????" is invalid
+PASS "u/**/+0/**/-0a" => "U+0-A"
 PASS "u+0-0a" => "U+0-A"
 PASS "u+000000-0aaaaa" => "U+0-AAAAA"
 PASS "u+0000000-0a" is invalid
@@ -74,8 +74,8 @@
 PASS "u+0+0a" is invalid
 PASS "u+0?-0a" is invalid
 PASS "u+0-0a?" is invalid
-FAIL "u+222222-22222a" is invalid assert_equals: expected "U+1357" but got "U+222222-22222A"
-FAIL "u/**/+0/**/-1" => "U+0-1" assert_equals: expected "U+0-1" but got "U+1357"
+PASS "u+222222-22222a" is invalid
+PASS "u/**/+0/**/-1" => "U+0-1"
 PASS "u+0-1" => "U+0-1"
 PASS "u-0-1" is invalid
 PASS "u-0+1" is invalid
@@ -83,12 +83,12 @@
 PASS "u+000000-000001" => "U+0-1"
 PASS "u+0000000-1" is invalid
 PASS "u+0-0000001" is invalid
-FAIL "u+0-222222" is invalid assert_equals: expected "U+1357" but got "U+0-222222"
-FAIL "u/**/+/**/?" => "U+0-F" assert_equals: expected "U+0-F" but got "U+1357"
+PASS "u+0-222222" is invalid
+PASS "u/**/+/**/?" => "U+0-F"
 PASS "u+?" => "U+0-F"
 PASS "u+?????" => "u+0-FFFFF"
 PASS "u+???????" is invalid
 PASS "u+?a" is invalid
-FAIL "u+??????" is invalid assert_equals: expected "U+1357" but got "U+0-FFFFFF"
-FAIL u+a is a valid selector assert_equals: expected "u + a" but got ".error"
+PASS "u+??????" is invalid
+PASS u+a is a valid selector
 

Modified: trunk/Source/WebCore/ChangeLog (279497 => 279498)


--- trunk/Source/WebCore/ChangeLog	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/ChangeLog	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,3 +1,80 @@
+2021-06-30  Darin Adler  <da...@apple.com>
+
+        CSS parser using a token for Unicode ranges, but recent CSS specification says it should not
+        https://bugs.webkit.org/show_bug.cgi?id=227569
+
+        Reviewed by Sam Weinig.
+
+        Tests: imported/w3c/web-platform-tests/css/css-syntax/unicode-range-selector.html
+               imported/w3c/web-platform-tests/css/css-syntax/urange-parsing.html
+
+        * css/parser/CSSParserToken.cpp:
+        (WebCore::CSSParserToken::CSSParserToken): Change the NumberToken constructor to
+        take a StringView so we can recover the original text if we need to parse it as
+        part of a Unicode range.
+        (WebCore::mergeIfAdjacent): Added. Helper used by convertToDimensionWithUnit.
+        (WebCore::CSSParserToken::convertToDimensionWithUnit): If the number token string
+        is adjacent to the dimension, then store the string containing both, so it can
+        be used if we need to parse it as part of a Unicode range. If the string is long,
+        then don't bother because a long string can't be part of such a range anyway. We
+        use 4 bits for the length, so can handle lengths in the range [1,15].
+        (WebCore::CSSParserToken::originalText const): Added. Used to recover the original
+        text for Unicode range parsing.
+        (WebCore::CSSParserToken::unitString const): Added. Used to get just the unit part
+        of the string for DimensionToken, since the full string now can include the number
+        as well in some cases (see above).
+        (WebCore::CSSParserToken::copyWithUpdatedString const): Changed the argument type
+        to StringView instead of using const& and added an assertion since this is only
+        safe if we are moving the backing characters, not changing the string contents.
+        (WebCore::CSSParserToken::valueDataCharRawEqual const): Deleted.
+        (WebCore::CSSParserToken::operator== const): Use StringView == operator instead of
+        our own valueDataCharRawEqual function. Also use unitString for DimensionToken.
+        (WebCore::CSSParserToken::serialize const): Use unitString for DimensionToken.
+        * css/parser/CSSParserToken.h: Updated for the above. Also deleted
+        UnicodeRangeToken, unicodeRangeStart, unicodeRangeEnd, and m_unicodeRange.
+
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::consumeResolutionCSSPrimitiveValueWithKnownTokenTypeDimension):
+        Use unitString for DimensionToken.
+        (WebCore::CSSPropertyParserHelpers::parseHexColor): Ditto.
+
+        * css/parser/CSSPropertyParserWorkerSafe.cpp:
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeOptionalDelimiter): Added.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeIdentifier): Added.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeAndAppendOptionalNumber): Added.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeAndAppendOptionalDelimiter): Added.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeAndAppendOptionalQuestionMarks): Added.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeUnicodeRangeString): Added.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeUnicodeRange): Added. Along with the
+        functions above, this implements the CSS specification's algorithm for consuming a Unicode
+        range, based on existing tokens without requiring a <urange> token.
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeFontFaceUnicodeRange): Call
+        the new consumeUnicodeRange function from this file instead of the old one that
+        depended on a <urange> token. Also refactored to use auto and to do the validity
+        check for the range as specified.
+
+        * css/parser/CSSSelectorParser.cpp:
+        (WebCore::consumeANPlusB): Use unitString for DimensionToken.
+
+        * css/parser/CSSTokenizer.cpp:
+        (WebCore::CSSTokenizer::letterU): Deleted.
+        (WebCore::CSSTokenizer::consumeNumber): Added code to pass in the original text
+        when constructing a NumberToken.
+        (WebCore::CSSTokenizer::consumeUnicodeRange): Deleted.
+
+        * css/parser/CSSTokenizer.h: Deleted consumeUnicodeRange.
+
+        * css/parser/SizesCalcParser.cpp:
+        (WebCore::SizesCalcParser::calcToReversePolishNotation): Removed case for
+        UnicodeRangeToken.
+
+        * dom/ConstantPropertyMap.cpp:
+        (WebCore::variableDataForPositivePixelLength): Pass a null StringView for the
+        original text when constructing a NumberToken. This is OK for now since this token
+        won't ever be parsed as part of a Unicode range, and we can change it if we ever
+        need to support originalText for any other cases.
+        (WebCore::variableDataForPositiveDuration): Ditto.
+
 2021-07-01  Ben Nham  <n...@apple.com>
 
         Unreviewed, reverting r279172.

Modified: trunk/Source/WebCore/css/parser/CSSParserToken.cpp (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSParserToken.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSParserToken.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,5 +1,5 @@
 // Copyright 2014 The Chromium Authors. All rights reserved.
-// Copyright (C) 2016 Apple Inc. All rights reserved.
+// Copyright (C) 2016-2021 Apple Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
@@ -238,26 +238,17 @@
     m_id = -1;
 }
 
-CSSParserToken::CSSParserToken(CSSParserTokenType type, double numericValue, NumericValueType numericValueType, NumericSign sign)
-    : m_type(type)
+CSSParserToken::CSSParserToken(double numericValue, NumericValueType numericValueType, NumericSign sign, StringView originalText)
+    : m_type(NumberToken)
     , m_blockType(NotBlock)
     , m_numericValueType(numericValueType)
     , m_numericSign(sign)
     , m_unit(static_cast<unsigned>(CSSUnitType::CSS_NUMBER))
+    , m_numericValue(numericValue)
 {
-    ASSERT(type == NumberToken);
-    m_numericValue = numericValue;
+    initValueFromStringView(originalText);
 }
 
-CSSParserToken::CSSParserToken(CSSParserTokenType type, UChar32 start, UChar32 end)
-    : m_type(UnicodeRangeToken)
-    , m_blockType(NotBlock)
-{
-    ASSERT_UNUSED(type, type == UnicodeRangeToken);
-    m_unicodeRange.start = start;
-    m_unicodeRange.end = end;
-}
-
 CSSParserToken::CSSParserToken(HashTokenType type, StringView value)
     : m_type(HashToken)
     , m_blockType(NotBlock)
@@ -266,12 +257,34 @@
     initValueFromStringView(value);
 }
 
+static StringView mergeIfAdjacent(StringView a, StringView b)
+{
+    if (a.is8Bit() && b.is8Bit()) {
+        auto characters = a.characters8();
+        if (characters + a.length() == b.characters8())
+            return { characters, a.length() + b.length() };
+    } else if (!a.is8Bit() && !b.is8Bit()) {
+        auto characters = a.characters16();
+        if (characters + a.length() == b.characters16())
+            return { characters, a.length() + b.length() };
+    }
+    return { };
+}
+
 void CSSParserToken::convertToDimensionWithUnit(StringView unit)
 {
     ASSERT(m_type == NumberToken);
+    auto originalNumberText = originalText();
+    auto originalNumberTextLength = originalNumberText.length();
+    auto string = unit;
+    if (originalNumberTextLength && originalNumberTextLength < 16) {
+        if (auto merged = mergeIfAdjacent(originalNumberText, unit))
+            string = merged;
+    }
     m_type = DimensionToken;
-    initValueFromStringView(unit);
     m_unit = static_cast<unsigned>(stringToUnitType(unit));
+    m_nonUnitPrefixLength = string == unit ? 0 : originalNumberTextLength;
+    initValueFromStringView(string);
 }
 
 void CSSParserToken::convertToPercentage()
@@ -281,6 +294,18 @@
     m_unit = static_cast<unsigned>(CSSUnitType::CSS_PERCENTAGE);
 }
 
+StringView CSSParserToken::originalText() const
+{
+    ASSERT(m_type == NumberToken || m_type == DimensionToken);
+    return value();
+}
+
+StringView CSSParserToken::unitString() const
+{
+    ASSERT(m_type == DimensionToken);
+    return value().substring(m_nonUnitPrefixLength);
+}
+
 UChar CSSParserToken::delimiter() const
 {
     ASSERT(m_type == DelimiterToken);
@@ -333,37 +358,54 @@
 
 bool CSSParserToken::hasStringBacking() const
 {
-    CSSParserTokenType tokenType = type();
-    return tokenType == IdentToken
-        || tokenType == FunctionToken
-        || tokenType == AtKeywordToken
-        || tokenType == HashToken
-        || tokenType == UrlToken
-        || tokenType == DimensionToken
-        || tokenType == StringToken;
+    switch (type()) {
+    case AtKeywordToken:
+    case DimensionToken:
+    case FunctionToken:
+    case HashToken:
+    case IdentToken:
+    case NumberToken:
+    case PercentageToken:
+    case StringToken:
+    case UrlToken:
+        return true;
+    case BadStringToken:
+    case BadUrlToken:
+    case CDCToken:
+    case CDOToken:
+    case ColonToken:
+    case ColumnToken:
+    case CommaToken:
+    case CommentToken:
+    case DashMatchToken:
+    case DelimiterToken:
+    case EOFToken:
+    case IncludeMatchToken:
+    case LeftBraceToken:
+    case LeftBracketToken:
+    case LeftParenthesisToken:
+    case PrefixMatchToken:
+    case RightBraceToken:
+    case RightBracketToken:
+    case RightParenthesisToken:
+    case SemicolonToken:
+    case SubstringMatchToken:
+    case SuffixMatchToken:
+    case WhitespaceToken:
+        return false;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
-CSSParserToken CSSParserToken::copyWithUpdatedString(const StringView& string) const
+CSSParserToken CSSParserToken::copyWithUpdatedString(StringView string) const
 {
+    ASSERT(value() == string);
     CSSParserToken copy(*this);
     copy.initValueFromStringView(string);
     return copy;
 }
 
-bool CSSParserToken::valueDataCharRawEqual(const CSSParserToken& other) const
-{
-    if (m_valueLength != other.m_valueLength)
-        return false;
-
-    if (m_valueDataCharRaw == other.m_valueDataCharRaw && m_valueIs8Bit == other.m_valueIs8Bit)
-        return true;
-
-    if (m_valueIs8Bit)
-        return other.m_valueIs8Bit ? equal(static_cast<const LChar*>(m_valueDataCharRaw), static_cast<const LChar*>(other.m_valueDataCharRaw), m_valueLength) : equal(static_cast<const LChar*>(m_valueDataCharRaw), static_cast<const UChar*>(other.m_valueDataCharRaw), m_valueLength);
-    
-    return other.m_valueIs8Bit ? equal(static_cast<const UChar*>(m_valueDataCharRaw), static_cast<const LChar*>(other.m_valueDataCharRaw), m_valueLength) : equal(static_cast<const UChar*>(m_valueDataCharRaw), static_cast<const UChar*>(other.m_valueDataCharRaw), m_valueLength);
-}
-
 bool CSSParserToken::operator==(const CSSParserToken& other) const
 {
     if (m_type != other.m_type)
@@ -379,16 +421,14 @@
     case FunctionToken:
     case StringToken:
     case UrlToken:
-        return valueDataCharRawEqual(other);
+        return value() == other.value();
     case DimensionToken:
-        if (!valueDataCharRawEqual(other))
+        if (unitString() != other.unitString())
             return false;
         FALLTHROUGH;
     case NumberToken:
     case PercentageToken:
         return m_numericSign == other.m_numericSign && m_numericValue == other.m_numericValue && m_numericValueType == other.m_numericValueType;
-    case UnicodeRangeToken:
-        return m_unicodeRange.start == other.m_unicodeRange.start && m_unicodeRange.end == other.m_unicodeRange.end;
     default:
         return true;
     }
@@ -496,12 +536,9 @@
     case DimensionToken:
         // This will incorrectly serialize e.g. 4e3e2 as 4000e2.
         builder.append(numericValue());
-        serializeIdentifier(value().toString(), builder);
+        serializeIdentifier(unitString().toString(), builder);
         appendCommentIfNeeded({ IdentToken, FunctionToken, UrlToken, BadUrlToken, NumberToken, PercentageToken, DimensionToken, CDCToken }, '-');
         break;
-    case UnicodeRangeToken:
-        builder.append("U+", hex(unicodeRangeStart()), '-', hex(unicodeRangeEnd()));
-        break;
     case StringToken:
         serializeString(value().toString(), builder);
         break;

Modified: trunk/Source/WebCore/css/parser/CSSParserToken.h (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSParserToken.h	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSParserToken.h	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,5 +1,5 @@
 // Copyright 2014 The Chromium Authors. All rights reserved.
-// Copyright (C) 2016 Apple Inc. All rights reserved.
+// Copyright (C) 2016-2021 Apple Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
@@ -51,7 +51,6 @@
     SuffixMatchToken,
     SubstringMatchToken,
     ColumnToken,
-    UnicodeRangeToken,
     WhitespaceToken,
     CDOToken,
     CDCToken,
@@ -102,8 +101,7 @@
     CSSParserToken(CSSParserTokenType, StringView, BlockType = NotBlock);
 
     CSSParserToken(CSSParserTokenType, UChar); // for DelimiterToken
-    CSSParserToken(CSSParserTokenType, double, NumericValueType, NumericSign); // for NumberToken
-    CSSParserToken(CSSParserTokenType, UChar32, UChar32); // for UnicodeRangeToken
+    CSSParserToken(double, NumericValueType, NumericSign, StringView originalText); // for NumberToken
 
     CSSParserToken(HashTokenType, StringView);
 
@@ -128,11 +126,11 @@
     NumericSign numericSign() const;
     NumericValueType numericValueType() const;
     double numericValue() const;
+    StringView originalText() const;
     HashTokenType getHashTokenType() const { ASSERT(m_type == HashToken); return m_hashTokenType; }
     BlockType getBlockType() const { return static_cast<BlockType>(m_blockType); }
     CSSUnitType unitType() const { return static_cast<CSSUnitType>(m_unit); }
-    UChar32 unicodeRangeStart() const { ASSERT(m_type == UnicodeRangeToken); return m_unicodeRange.start; }
-    UChar32 unicodeRangeEnd() const { ASSERT(m_type == UnicodeRangeToken); return m_unicodeRange.end; }
+    StringView unitString() const;
     CSSValueID id() const;
     CSSValueID functionId() const;
 
@@ -142,7 +140,7 @@
 
     void serialize(StringBuilder&, const CSSParserToken* nextToken = nullptr) const;
 
-    CSSParserToken copyWithUpdatedString(const StringView&) const;
+    CSSParserToken copyWithUpdatedString(StringView) const;
 
 private:
     void initValueFromStringView(StringView string)
@@ -149,7 +147,7 @@
     {
         m_valueLength = string.length();
         m_valueIs8Bit = string.is8Bit();
-        m_valueDataCharRaw = m_valueIs8Bit ? const_cast<void*>(static_cast<const void*>(string.characters8())) : const_cast<void*>(static_cast<const void*>(string.characters16()));
+        m_valueDataCharRaw = m_valueIs8Bit ? static_cast<const void*>(string.characters8()) : static_cast<const void*>(string.characters16());
     }
     unsigned m_type : 6; // CSSParserTokenType
     unsigned m_blockType : 2; // BlockType
@@ -156,14 +154,13 @@
     unsigned m_numericValueType : 1; // NumericValueType
     unsigned m_numericSign : 2; // NumericSign
     unsigned m_unit : 7; // CSSUnitType
+    unsigned m_nonUnitPrefixLength : 4; // Only for DimensionType, only needs to be long enough for UnicodeRange parsing.
 
-    bool valueDataCharRawEqual(const CSSParserToken& other) const;
-
     // m_value... is an unpacked StringView so that we can pack it
     // tightly with the rest of this object for a smaller object size.
     bool m_valueIs8Bit : 1;
     unsigned m_valueLength;
-    void* m_valueDataCharRaw; // Either LChar* or UChar*.
+    const void* m_valueDataCharRaw; // Either LChar* or UChar*.
 
     union {
         UChar m_delimiter;
@@ -170,11 +167,6 @@
         HashTokenType m_hashTokenType;
         double m_numericValue;
         mutable int m_id;
-
-        struct {
-            UChar32 start;
-            UChar32 end;
-        } m_unicodeRange;
     };
 };
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -634,7 +634,7 @@
 
     if (auto unit = range.peek().unitType(); unit == CSSUnitType::CSS_DPPX || unit == CSSUnitType::CSS_DPI || unit == CSSUnitType::CSS_DPCM)
         return pool.createValue(range.consumeIncludingWhitespace().numericValue(), unit);
-    if (allowX == AllowXResolutionUnit::Allow && range.peek().value() == "x")
+    if (allowX == AllowXResolutionUnit::Allow && range.peek().unitString() == "x")
         return pool.createValue(range.consumeIncludingWhitespace().numericValue(), CSSUnitType::CSS_DPPX);
 
     return nullptr;
@@ -2456,7 +2456,7 @@
             if (token.type() == NumberToken)
                 string = String::number(integerValue); // e.g. 112233
             else
-                string = makeString(integerValue, token.value()); // e.g. 0001FF
+                string = makeString(integerValue, token.unitString()); // e.g. 0001FF
             if (string.length() < 6)
                 string = makeString(&"000000"[string.length()], string);
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -1,5 +1,5 @@
 // Copyright 2015 The Chromium Authors. All rights reserved.
-// Copyright (C) 2016 Apple Inc. All rights reserved.
+// Copyright (C) 2016-2021 Apple Inc. All rights reserved.
 // Copyright (C) 2021 Metrological Group B.V.
 // Copyright (C) 2021 Igalia S.L.
 //
@@ -393,23 +393,126 @@
 }
 #endif
 
+static bool consumeOptionalDelimiter(CSSParserTokenRange& range, UChar value)
+{
+    if (!(range.peek().type() == DelimiterToken && range.peek().delimiter() == value))
+        return false;
+    range.consume();
+    return true;
+}
+
+static StringView consumeIdentifier(CSSParserTokenRange& range)
+{
+    if (range.peek().type() != IdentToken)
+        return { };
+    return range.consume().value();
+}
+
+static bool consumeAndAppendOptionalNumber(StringBuilder& builder, CSSParserTokenRange& range, CSSParserTokenType type = NumberToken)
+{
+    if (range.peek().type() != type)
+        return false;
+    auto originalText = range.consume().originalText();
+    if (originalText.isNull())
+        return false;
+    builder.append(originalText);
+    return true;
+}
+
+static bool consumeAndAppendOptionalDelimiter(StringBuilder& builder, CSSParserTokenRange& range, UChar value)
+{
+    if (!consumeOptionalDelimiter(range, value))
+        return false;
+    builder.append(value);
+    return true;
+}
+
+static void consumeAndAppendOptionalQuestionMarks(StringBuilder& builder, CSSParserTokenRange& range)
+{
+    while (consumeAndAppendOptionalDelimiter(builder, range, '?')) { }
+}
+
+static String consumeUnicodeRangeString(CSSParserTokenRange& range)
+{
+    if (!equalLettersIgnoringASCIICase(consumeIdentifier(range), "u"))
+        return { };
+    StringBuilder builder;
+    if (consumeAndAppendOptionalNumber(builder, range, DimensionToken))
+        consumeAndAppendOptionalQuestionMarks(builder, range);
+    else if (consumeAndAppendOptionalNumber(builder, range)) {
+        if (!(consumeAndAppendOptionalNumber(builder, range, DimensionToken) || consumeAndAppendOptionalNumber(builder, range)))
+            consumeAndAppendOptionalQuestionMarks(builder, range);
+    } else if (consumeOptionalDelimiter(range, '+')) {
+        builder.append('+');
+        if (auto identifier = consumeIdentifier(range); !identifier.isNull())
+            builder.append(identifier);
+        else if (!consumeAndAppendOptionalDelimiter(builder, range, '?'))
+            return { };
+        consumeAndAppendOptionalQuestionMarks(builder, range);
+    } else
+        return { };
+    return builder.toString();
+}
+
+struct UnicodeRange {
+    UChar32 start;
+    UChar32 end;
+};
+
+static std::optional<UnicodeRange> consumeUnicodeRange(CSSParserTokenRange& range)
+{
+    return readCharactersForParsing(consumeUnicodeRangeString(range), [&](auto buffer) -> std::optional<UnicodeRange> {
+        if (!skipExactly(buffer, '+'))
+            return std::nullopt;
+        UChar32 start = 0;
+        unsigned hexDigitCount = 0;
+        while (buffer.hasCharactersRemaining() && isASCIIHexDigit(*buffer)) {
+            if (++hexDigitCount > 6)
+                return std::nullopt;
+            start <<= 4;
+            start |= toASCIIHexValue(*buffer++);
+        }
+        auto end = start;
+        while (skipExactly(buffer, '?')) {
+            if (++hexDigitCount > 6)
+                return std::nullopt;
+            start <<= 4;
+            end <<= 4;
+            end |= 0xF;
+        }
+        if (!hexDigitCount)
+            return std::nullopt;
+        if (start == end && buffer.hasCharactersRemaining()) {
+            if (!skipExactly(buffer, '-'))
+                return std::nullopt;
+            end = 0;
+            hexDigitCount = 0;
+            while (buffer.hasCharactersRemaining() && isASCIIHexDigit(*buffer)) {
+                if (++hexDigitCount > 6)
+                    return std::nullopt;
+                end <<= 4;
+                end |= toASCIIHexValue(*buffer++);
+            }
+            if (!hexDigitCount)
+                return std::nullopt;
+        }
+        if (buffer.hasCharactersRemaining())
+            return std::nullopt;
+        return { { start, end } };
+    });
+}
+
 RefPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParserTokenRange& range)
 {
-    RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-
+    auto values = CSSValueList::createCommaSeparated();
     do {
-        const CSSParserToken& token = range.consumeIncludingWhitespace();
-        if (token.type() != UnicodeRangeToken)
+        auto unicodeRange = consumeUnicodeRange(range);
+        range.consumeWhitespace();
+        if (!unicodeRange || unicodeRange->end > UCHAR_MAX_VALUE || unicodeRange->start > unicodeRange->end)
             return nullptr;
-
-        UChar32 start = token.unicodeRangeStart();
-        UChar32 end = token.unicodeRangeEnd();
-        if (start > end)
-            return nullptr;
-        values->append(CSSUnicodeRangeValue::create(start, end));
+        values->append(CSSUnicodeRangeValue::create(unicodeRange->start, unicodeRange->end));
     } while (CSSPropertyParserHelpers::consumeCommaIncludingWhitespace(range));
-
-    return values;
+    return WTFMove(values);
 }
 
 static RefPtr<CSSFontFeatureValue> consumeFontFeatureTag(CSSParserTokenRange& range)

Modified: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -868,7 +868,7 @@
         nString = range.consume().value().toString();
     } else if (token.type() == DimensionToken && token.numericValueType() == IntegerValueType) {
         result.first = token.numericValue();
-        nString = token.value().toString();
+        nString = token.unitString().toString();
     } else if (token.type() == IdentToken) {
         if (token.value()[0] == '-') {
             result.first = -1;

Modified: trunk/Source/WebCore/css/parser/CSSTokenizer.cpp (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSTokenizer.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSTokenizer.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -355,16 +355,6 @@
     return consumeNumericToken();
 }
 
-CSSParserToken CSSTokenizer::letterU(UChar cc)
-{
-    if (m_input.peek(0) == '+' && (isASCIIHexDigit(m_input.peek(1)) || m_input.peek(1) == '?')) {
-        m_input.advance();
-        return consumeUnicodeRange();
-    }
-    reconsume(cc);
-    return consumeIdentLikeToken();
-}
-
 CSSParserToken CSSTokenizer::nameStart(UChar cc)
 {
     reconsume(cc);
@@ -467,12 +457,12 @@
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
-    &CSSTokenizer::letterU,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
+    &CSSTokenizer::nameStart,
     &CSSTokenizer::leftBracket,
     &CSSTokenizer::reverseSolidus,
     &CSSTokenizer::rightBracket,
@@ -499,12 +489,12 @@
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
-    &CSSTokenizer::letterU,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
     &CSSTokenizer::nameStart,
+    &CSSTokenizer::nameStart,
     &CSSTokenizer::leftBrace,
     &CSSTokenizer::verticalLine,
     &CSSTokenizer::rightBrace,
@@ -545,6 +535,8 @@
 {
     ASSERT(nextCharsAreNumber());
 
+    auto startOffset = m_input.offset();
+
     NumericValueType type = IntegerValueType;
     NumericSign sign = NoSign;
     unsigned numberLength = 0;
@@ -580,7 +572,7 @@
     double value = m_input.getDouble(0, numberLength);
     m_input.advance(numberLength);
 
-    return CSSParserToken(NumberToken, value, type, sign);
+    return CSSParserToken(value, type, sign, m_input.rangeAt(startOffset, m_input.offset() - startOffset));
 }
 
 // http://www.w3.org/TR/css3-syntax/#consume-a-numeric-token
@@ -652,37 +644,6 @@
     }
 }
 
-CSSParserToken CSSTokenizer::consumeUnicodeRange()
-{
-    ASSERT(isASCIIHexDigit(m_input.peek(0)) || m_input.peek(0) == '?');
-    int lengthRemaining = 6;
-    UChar32 start = 0;
-
-    while (lengthRemaining && isASCIIHexDigit(m_input.peek(0))) {
-        start = start * 16 + toASCIIHexValue(consume());
-        --lengthRemaining;
-    }
-
-    UChar32 end = start;
-    if (lengthRemaining && consumeIfNext('?')) {
-        do {
-            start *= 16;
-            end = end * 16 + 0xF;
-            --lengthRemaining;
-        } while (lengthRemaining && consumeIfNext('?'));
-    } else if (m_input.peek(0) == '-' && isASCIIHexDigit(m_input.peek(1))) {
-        m_input.advance();
-        lengthRemaining = 6;
-        end = 0;
-        do {
-            end = end * 16 + toASCIIHexValue(consume());
-            --lengthRemaining;
-        } while (lengthRemaining && isASCIIHexDigit(m_input.peek(0)));
-    }
-
-    return CSSParserToken(UnicodeRangeToken, start, end);
-}
-
 // http://dev.w3.org/csswg/css-syntax/#non-printable-code-point
 static bool isNonPrintableCodePoint(UChar cc)
 {

Modified: trunk/Source/WebCore/css/parser/CSSTokenizer.h (279497 => 279498)


--- trunk/Source/WebCore/css/parser/CSSTokenizer.h	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/CSSTokenizer.h	2021-07-02 06:37:39 UTC (rev 279498)
@@ -68,7 +68,6 @@
     CSSParserToken consumeIdentLikeToken();
     CSSParserToken consumeNumber();
     CSSParserToken consumeStringTokenUntil(UChar);
-    CSSParserToken consumeUnicodeRange();
     CSSParserToken consumeUrlToken();
 
     void consumeBadUrlRemnants();

Modified: trunk/Source/WebCore/css/parser/SizesCalcParser.cpp (279497 => 279498)


--- trunk/Source/WebCore/css/parser/SizesCalcParser.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/css/parser/SizesCalcParser.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -167,7 +167,6 @@
         case SuffixMatchToken:
         case SubstringMatchToken:
         case ColumnToken:
-        case UnicodeRangeToken:
         case IdentToken:
         case CommaToken:
         case ColonToken:

Modified: trunk/Source/WebCore/dom/ConstantPropertyMap.cpp (279497 => 279498)


--- trunk/Source/WebCore/dom/ConstantPropertyMap.cpp	2021-07-02 06:01:51 UTC (rev 279497)
+++ trunk/Source/WebCore/dom/ConstantPropertyMap.cpp	2021-07-02 06:37:39 UTC (rev 279498)
@@ -105,7 +105,7 @@
 {
     ASSERT(lengthInPx >= 0);
 
-    CSSParserToken token(NumberToken, lengthInPx, NumberValueType, NoSign);
+    CSSParserToken token(lengthInPx, NumberValueType, NoSign, { });
     token.convertToDimensionWithUnit("px");
 
     Vector<CSSParserToken> tokens { token };
@@ -117,7 +117,7 @@
 {
     ASSERT(durationInSeconds >= 0_s);
 
-    CSSParserToken token(NumberToken, durationInSeconds.value(), NumberValueType, NoSign);
+    CSSParserToken token(durationInSeconds.value(), NumberValueType, NoSign, { });
     token.convertToDimensionWithUnit("s");
 
     Vector<CSSParserToken> tokens { token };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to