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 };