Changeset 292816 in webkit


Ignore:
Timestamp:
Apr 13, 2022 11:48:19 AM (3 months ago)
Author:
Antti Koivisto
Message:

[CSS Container Queries] Limit query range syntax
https://bugs.webkit.org/show_bug.cgi?id=239118

Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

  • web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt:

Source/WebCore:

The spec disallows things like (100px = width < 200px) and (100px < width > 200px).

https://www.w3.org/TR/mediaqueries-4/#mq-range-context

  • css/ContainerQueryParser.cpp:

(WebCore::ContainerQueryParser::consumeContainerQuery):

Try as a condition first.
Return UnknownQuery on parse failure.

(WebCore::ContainerQueryParser::consumeRangeSizeFeature):

Validate the ranges so what ends up being allowed matches the spec productions.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r292804 r292816  
     12022-04-13  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Limit query range syntax
     4        https://bugs.webkit.org/show_bug.cgi?id=239118
     5
     6        Reviewed by Simon Fraser.
     7
     8        * web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt:
     9
    1102022-04-13  Youenn Fablet  <youenn@apple.com>
    211
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt

    r292759 r292816  
    5252PASS (grid)
    5353PASS (width == 100px)
    54 FAIL (100px == width) assert_equals: expected 2 but got 0
    55 FAIL (100px = width = 200px) assert_equals: expected "" but got "true"
    56 FAIL (100px < width > 200px) assert_equals: expected "" but got "true"
    57 FAIL (100px <= width >= 200px) assert_equals: expected "" but got "true"
    58 FAIL (100px <= width > 200px) assert_equals: expected "" but got "true"
    59 FAIL (100px < width >= 200px) assert_equals: expected "" but got "true"
    60 FAIL (100px : width : 200px) assert_equals: expected 2 but got 0
     54PASS (100px == width)
     55PASS (100px = width = 200px)
     56PASS (100px < width > 200px)
     57PASS (100px <= width >= 200px)
     58PASS (100px <= width > 200px)
     59PASS (100px < width >= 200px)
     60PASS (100px : width : 200px)
    6161PASS screen
    6262PASS print
  • trunk/Source/WebCore/ChangeLog

    r292812 r292816  
     12022-04-13  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Limit query range syntax
     4        https://bugs.webkit.org/show_bug.cgi?id=239118
     5
     6        Reviewed by Simon Fraser.
     7
     8        The spec disallows things like (100px = width < 200px) and (100px < width > 200px).
     9
     10        https://www.w3.org/TR/mediaqueries-4/#mq-range-context
     11
     12        * css/ContainerQueryParser.cpp:
     13        (WebCore::ContainerQueryParser::consumeContainerQuery):
     14
     15        Try as a condition first.
     16        Return UnknownQuery on parse failure.
     17
     18        (WebCore::ContainerQueryParser::consumeRangeSizeFeature):
     19
     20        Validate the ranges so what ends up being allowed matches the spec productions.
     21
    1222022-04-13  Simon Fraser  <simon.fraser@apple.com>
    223
  • trunk/Source/WebCore/css/ContainerQueryParser.cpp

    r292375 r292816  
    7474        blockRange.consumeWhitespace();
    7575
    76         // Try to parse as a size query first.
    77         auto blockForSizeFeature = blockRange;
    78         if (auto sizeFeature = consumeSizeFeature(blockForSizeFeature))
     76        // Try to parse as a condition first.
     77        auto conditionRange = blockRange;
     78        if (auto condition = consumeCondition<CQ::ContainerCondition>(conditionRange))
     79            return { condition };
     80
     81        if (auto sizeFeature = consumeSizeFeature(blockRange))
    7982            return { *sizeFeature };
    8083
    81         if (auto condition = consumeCondition<CQ::ContainerCondition>(blockRange))
    82             return { condition };
     84        return CQ::UnknownQuery { { }, blockRange.serialize() };
    8385    }
    8486
     
    156158
    157159    auto sizeFeature = consume();
     160
     161    if (!range.atEnd())
     162        return { };
     163
    158164    if (sizeFeature)
    159165        m_requiredAxes.add(CQ::requiredAxesForFeature(sizeFeature->name));
     
    204210
    205211    auto value = consumeValue(range);
     212    if (!value)
     213        return { };
    206214
    207215    return CQ::SizeFeature { featureName, CQ::Syntax::Colon, { }, CQ::Comparison { op, WTFMove(value) } };
     
    240248    };
    241249
     250    bool didFailParsing = false;
     251
    242252    auto consumeLeftComparison = [&]() -> std::optional<CQ::Comparison> {
    243253        if (range.peek().type() == IdentToken)
    244254            return { };
    245255        auto value = consumeValue(range);
     256        if (!value)
     257            return { };
    246258        auto op = consumeRangeOperator();
    247         if (!op)
    248             return { };
     259        if (!op) {
     260            didFailParsing = true;
     261            return { };
     262        }
    249263
    250264        return CQ::Comparison { *op, WTFMove(value) };
     
    256270            return { };
    257271        auto value = consumeValue(range);
     272        if (!value) {
     273            didFailParsing = true;
     274            return { };
     275        }
    258276
    259277        return CQ::Comparison { *op, WTFMove(value) };
     
    268286    auto rightComparison = consumeRightComparison();
    269287
    270     if (!leftComparison && !rightComparison)
     288    auto validateComparisons = [&] {
     289        if (didFailParsing)
     290            return false;
     291        if (!leftComparison && !rightComparison)
     292            return false;
     293        if (!leftComparison || !rightComparison)
     294            return true;
     295        // Disallow comparisons like (a=b=c), (a=b<c).
     296        if (leftComparison->op == CQ::ComparisonOperator::Equal || rightComparison->op == CQ::ComparisonOperator::Equal)
     297            return false;
     298        // Disallow comparisons like (a<b>c).
     299        bool leftIsLess = leftComparison->op == CQ::ComparisonOperator::LessThan || leftComparison->op == CQ::ComparisonOperator::LessThanOrEqual;
     300        bool rightIsLess = rightComparison->op == CQ::ComparisonOperator::LessThan || rightComparison->op == CQ::ComparisonOperator::LessThanOrEqual;
     301        return leftIsLess == rightIsLess;
     302    };
     303
     304    if (!validateComparisons())
    271305        return { };
    272306
     
    284318    if (auto value = CSSPropertyParserHelpers::consumeAspectRatioValue(range))
    285319        return value;
    286     range.consumeIncludingWhitespace();
    287320    return nullptr;
    288321}
Note: See TracChangeset for help on using the changeset viewer.