Changeset 207536 in webkit


Ignore:
Timestamp:
Oct 19, 2016 8:07:19 AM (8 years ago)
Author:
hyatt@apple.com
Message:

[CSS Parser] Fix compound selector parsing.
https://bugs.webkit.org/show_bug.cgi?id=163649

Reviewed by Darin Adler.

The new CSS parser is failing to handle compound selectors. The code has an assumption that the
first value in the RelationType enum is SubSelector. This patch changes the enum to have the same
name used in Blink, RelationType, and to make the ordering be exactly the same.

  • css/CSSSelector.h:

(WebCore::CSSSelector::relation):
(WebCore::CSSSelector::setRelation):

  • css/SelectorChecker.cpp:

(WebCore::SelectorChecker::matchRecursively):
(WebCore::canMatchHoverOrActiveInQuirksMode):
(WebCore::SelectorChecker::determineLinkMatchType):

  • css/SelectorFilter.cpp:

(WebCore::SelectorFilter::collectIdentifierHashes):

  • css/parser/CSSParserValues.cpp:

(WebCore::CSSParserSelector::insertTagHistory):
(WebCore::CSSParserSelector::appendTagHistory):

  • css/parser/CSSParserValues.h:

(WebCore::CSSParserSelector::setRelation):

  • css/parser/CSSSelectorParser.cpp:

(WebCore::CSSSelectorParser::consumeComplexSelector):
(WebCore::CSSSelectorParser::consumeCombinator):

  • css/parser/CSSSelectorParser.h:
  • cssjit/SelectorCompiler.cpp:

(WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
(WebCore::SelectorCompiler::constructFragmentsInternal):

Location:
trunk/Source/WebCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207535 r207536  
     12016-10-18  Dave Hyatt  <hyatt@apple.com>
     2
     3        [CSS Parser] Fix compound selector parsing.
     4        https://bugs.webkit.org/show_bug.cgi?id=163649
     5
     6        Reviewed by Darin Adler.
     7
     8        The new CSS parser is failing to handle compound selectors. The code has an assumption that the
     9        first value in the RelationType enum is SubSelector. This patch changes the enum to have the same
     10        name used in Blink, RelationType, and to make the ordering be exactly the same.
     11
     12        * css/CSSSelector.h:
     13        (WebCore::CSSSelector::relation):
     14        (WebCore::CSSSelector::setRelation):
     15        * css/SelectorChecker.cpp:
     16        (WebCore::SelectorChecker::matchRecursively):
     17        (WebCore::canMatchHoverOrActiveInQuirksMode):
     18        (WebCore::SelectorChecker::determineLinkMatchType):
     19        * css/SelectorFilter.cpp:
     20        (WebCore::SelectorFilter::collectIdentifierHashes):
     21        * css/parser/CSSParserValues.cpp:
     22        (WebCore::CSSParserSelector::insertTagHistory):
     23        (WebCore::CSSParserSelector::appendTagHistory):
     24        * css/parser/CSSParserValues.h:
     25        (WebCore::CSSParserSelector::setRelation):
     26        * css/parser/CSSSelectorParser.cpp:
     27        (WebCore::CSSSelectorParser::consumeComplexSelector):
     28        (WebCore::CSSSelectorParser::consumeCombinator):
     29        * css/parser/CSSSelectorParser.h:
     30        * cssjit/SelectorCompiler.cpp:
     31        (WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
     32        (WebCore::SelectorCompiler::constructFragmentsInternal):
     33
    1342016-10-19  Javier Fernandez  <jfernandez@igalia.com>
    235
  • trunk/Source/WebCore/css/CSSSelector.cpp

    r205660 r207536  
    4747};
    4848
     49static_assert(CSSSelector::RelationType::Subselector == 0, "Subselector must be 0 for consumeCombinator.");
    4950static_assert(sizeof(CSSSelector) == sizeof(SameSizeAsCSSSelector), "CSSSelector should remain small.");
    5051
     
    721722        }
    722723
    723         if (cs->relation() != CSSSelector::SubSelector || !cs->tagHistory())
     724        if (cs->relation() != CSSSelector::Subselector || !cs->tagHistory())
    724725            break;
    725726        cs = cs->tagHistory();
     
    742743        case CSSSelector::IndirectAdjacent:
    743744            return tagHistory->selectorText(" ~ " + str.toString() + rightSide);
    744         case CSSSelector::SubSelector:
     745        case CSSSelector::Subselector:
    745746            ASSERT_NOT_REACHED();
    746747#if ASSERT_DISABLED
  • trunk/Source/WebCore/css/CSSSelector.h

    r205660 r207536  
    8282        };
    8383
    84         enum Relation {
    85             Descendant = 0,
     84        enum RelationType {
     85            Subselector,
     86            Descendant,
    8687            Child,
    8788            DirectAdjacent,
    8889            IndirectAdjacent,
    89             SubSelector,
    9090            ShadowDescendant, // FIXME-NEWPARSER: Remove this in favor of the new shadow values below.
    9191            ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
     
    296296        bool isAttributeSelector() const;
    297297
    298         Relation relation() const { return static_cast<Relation>(m_relation); }
    299         void setRelation(Relation relation)
     298        RelationType relation() const { return static_cast<RelationType>(m_relation); }
     299        void setRelation(RelationType relation)
    300300        {
    301301            m_relation = relation;
     
    327327
    328328    private:
    329         unsigned m_relation              : 3; // enum Relation.
     329        unsigned m_relation              : 3; // enum RelationType.
    330330        mutable unsigned m_match         : 4; // enum Match.
    331331        mutable unsigned m_pseudoType    : 8; // PseudoType.
  • trunk/Source/WebCore/css/CSSSelectorList.cpp

    r204591 r207536  
    132132void CSSSelectorList::buildSelectorsText(StringBuilder& stringBuilder) const
    133133{
    134     const CSSSelector* firstSubSelector = first();
    135     for (const CSSSelector* subSelector = firstSubSelector; subSelector; subSelector = CSSSelectorList::next(subSelector)) {
    136         if (subSelector != firstSubSelector)
     134    const CSSSelector* firstSubselector = first();
     135    for (const CSSSelector* subSelector = firstSubselector; subSelector; subSelector = CSSSelectorList::next(subSelector)) {
     136        if (subSelector != firstSubselector)
    137137            stringBuilder.appendLiteral(", ");
    138138        stringBuilder.append(subSelector->selectorText());
  • trunk/Source/WebCore/css/RuleSet.cpp

    r207077 r207536  
    123123        }
    124124
    125         if (selector->relation() != CSSSelector::SubSelector)
     125        if (selector->relation() != CSSSelector::Subselector)
    126126            matchesRightmostElement = false;
    127127
     
    269269            return;
    270270        }
    271         if (selector->relation() != CSSSelector::SubSelector)
     271        if (selector->relation() != CSSSelector::Subselector)
    272272            break;
    273273        selector = selector->tagHistory();
  • trunk/Source/WebCore/css/SelectorChecker.cpp

    r207513 r207536  
    312312
    313313    // The rest of the selectors has to match
    314     CSSSelector::Relation relation = context.selector->relation();
     314    auto relation = context.selector->relation();
    315315
    316316    // Prepare next selector
     
    322322    nextContext.selector = leftSelector;
    323323
    324     if (relation != CSSSelector::SubSelector) {
     324    if (relation != CSSSelector::Subselector) {
    325325        // Bail-out if this selector is irrelevant for the pseudoId
    326326        if (context.pseudoId != NOPSEUDO && !dynamicPseudoIdSet.has(context.pseudoId))
     
    417417        return MatchResult::fails(Match::SelectorFailsAllSiblings);
    418418
    419     case CSSSelector::SubSelector:
     419    case CSSSelector::Subselector:
    420420        {
    421421            // a selector is invalid if something follows a pseudo-element
     
    635635        }
    636636
    637         CSSSelector::Relation relation = selector->relation();
     637        auto relation = selector->relation();
    638638        if (relation == CSSSelector::ShadowDescendant)
    639639            return true;
    640640
    641         if (relation != CSSSelector::SubSelector)
     641        if (relation != CSSSelector::Subselector)
    642642            return false;
    643643    }
     
    12021202            }
    12031203        }
    1204         CSSSelector::Relation relation = selector->relation();
    1205         if (relation == CSSSelector::SubSelector)
     1204        auto relation = selector->relation();
     1205        if (relation == CSSSelector::Subselector)
    12061206            continue;
    12071207        if (relation != CSSSelector::Descendant && relation != CSSSelector::Child)
  • trunk/Source/WebCore/css/SelectorFilter.cpp

    r205660 r207536  
    123123    unsigned* hash = identifierHashes;
    124124    unsigned* end = identifierHashes + maximumIdentifierCount;
    125     CSSSelector::Relation relation = selector->relation();
     125    auto relation = selector->relation();
    126126
    127127    // Skip the topmost selector. It is handled quickly by the rule hashes.
     
    130130        // Only collect identifiers that match ancestors.
    131131        switch (relation) {
    132         case CSSSelector::SubSelector:
     132        case CSSSelector::Subselector:
    133133            if (!skipOverSubselectors)
    134134                collectDescendantSelectorIdentifierHashes(selector, hash);
  • trunk/Source/WebCore/css/parser/CSSParser.cpp

    r207499 r207536  
    1298212982    if (specifiers->isCustomPseudoElement()) {
    1298312983        // Specifiers for unknown pseudo element go right behind it in the chain.
    12984         specifiers->insertTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier), CSSSelector::ShadowDescendant);
     12984        specifiers->insertTagHistory(CSSSelector::Subselector, WTFMove(newSpecifier), CSSSelector::ShadowDescendant);
    1298512985        return specifiers;
    1298612986    }
    12987     specifiers->appendTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier));
     12987    specifiers->appendTagHistory(CSSSelector::Subselector, WTFMove(newSpecifier));
    1298812988    return specifiers;
    1298912989}
  • trunk/Source/WebCore/css/parser/CSSParserValues.cpp

    r207513 r207536  
    448448}
    449449
    450 void CSSParserSelector::insertTagHistory(CSSSelector::Relation before, std::unique_ptr<CSSParserSelector> selector, CSSSelector::Relation after)
     450void CSSParserSelector::insertTagHistory(CSSSelector::RelationType before, std::unique_ptr<CSSParserSelector> selector, CSSSelector::RelationType after)
    451451{
    452452    if (m_tagHistory)
     
    457457}
    458458
    459 void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, std::unique_ptr<CSSParserSelector> selector)
     459void CSSParserSelector::appendTagHistory(CSSSelector::RelationType relation, std::unique_ptr<CSSParserSelector> selector)
    460460{
    461461    CSSParserSelector* end = this;
     
    473473        end = end->tagHistory();
    474474
    475     CSSSelector::Relation selectorRelation;
     475    CSSSelector::RelationType selectorRelation;
    476476    switch (relation) {
    477477    case CSSParserSelectorCombinator::Child:
     
    520520
    521521    m_selector = std::make_unique<CSSSelector>(tagQName, tagIsForNamespaceRule);
    522     m_selector->setRelation(CSSSelector::SubSelector);
     522    m_selector->setRelation(CSSSelector::Subselector);
    523523}
    524524
    525525std::unique_ptr<CSSParserSelector> CSSParserSelector::releaseTagHistory()
    526526{
    527     setRelation(CSSSelector::SubSelector);
     527    setRelation(CSSSelector::Subselector);
    528528    return WTFMove(m_tagHistory);
    529529}
  • trunk/Source/WebCore/css/parser/CSSParserValues.h

    r207513 r207536  
    227227    void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector->setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
    228228    void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
    229     void setRelation(CSSSelector::Relation value) { m_selector->setRelation(value); }
     229    void setRelation(CSSSelector::RelationType value) { m_selector->setRelation(value); }
    230230    void setForPage() { m_selector->setForPage(); }
    231231
     
    262262    void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTFMove(selector); }
    263263    void clearTagHistory() { m_tagHistory.reset(); }
    264     void insertTagHistory(CSSSelector::Relation before, std::unique_ptr<CSSParserSelector>, CSSSelector::Relation after);
    265     void appendTagHistory(CSSSelector::Relation, std::unique_ptr<CSSParserSelector>);
     264    void insertTagHistory(CSSSelector::RelationType before, std::unique_ptr<CSSParserSelector>, CSSSelector::RelationType after);
     265    void appendTagHistory(CSSSelector::RelationType, std::unique_ptr<CSSParserSelector>);
    266266    void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr<CSSParserSelector>);
    267267    void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false);
  • trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp

    r207513 r207536  
    133133        return nullptr;
    134134
    135 
    136135    unsigned previousCompoundFlags = 0;
    137136
     
    139138        previousCompoundFlags |= extractCompoundFlags(*simple, m_context.mode);
    140139
    141     while (CSSSelector::Relation combinator = consumeCombinator(range)) {
     140    while (auto combinator = consumeCombinator(range)) {
    142141        std::unique_ptr<CSSParserSelector> nextSelector = consumeCompoundSelector(range);
    143142        if (!nextSelector)
     
    534533}
    535534
    536 CSSSelector::Relation CSSSelectorParser::consumeCombinator(CSSParserTokenRange& range)
    537 {
    538     CSSSelector::Relation fallbackResult = CSSSelector::SubSelector;
     535CSSSelector::RelationType CSSSelectorParser::consumeCombinator(CSSParserTokenRange& range)
     536{
     537    auto fallbackResult = CSSSelector::Subselector;
    539538    while (range.peek().type() == WhitespaceToken) {
    540539        range.consume();
     
    733732std::unique_ptr<CSSParserSelector> CSSSelectorParser::addSimpleSelectorToCompound(std::unique_ptr<CSSParserSelector> compoundSelector, std::unique_ptr<CSSParserSelector> simpleSelector)
    734733{
    735     compoundSelector->appendTagHistory(CSSSelector::SubSelector, WTFMove(simpleSelector));
     734    compoundSelector->appendTagHistory(CSSSelector::Subselector, WTFMove(simpleSelector));
    736735    return compoundSelector;
    737736}
     
    744743    //
    745744    // ".a.b > div#id" is stored in a tagHistory as [div, #id, .a, .b], each element in the
    746     // list stored with an associated relation (combinator or SubSelector).
     745    // list stored with an associated relation (combinator or Subselector).
    747746    //
    748747    // ::cue, ::shadow, and custom pseudo elements have an implicit ShadowPseudo combinator
  • trunk/Source/WebCore/css/parser/CSSSelectorParser.h

    r205660 r207536  
    6969    std::unique_ptr<CSSParserSelector> consumeAttribute(CSSParserTokenRange&);
    7070
    71     CSSSelector::Relation consumeCombinator(CSSParserTokenRange&);
     71    CSSSelector::RelationType consumeCombinator(CSSParserTokenRange&);
    7272    CSSSelector::Match consumeAttributeMatch(CSSParserTokenRange&);
    7373    CSSSelector::AttributeMatchType consumeAttributeFlags(CSSParserTokenRange&);
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r205660 r207536  
    399399}
    400400
    401 static inline FragmentRelation fragmentRelationForSelectorRelation(CSSSelector::Relation relation)
     401static inline FragmentRelation fragmentRelationForSelectorRelation(CSSSelector::RelationType relation)
    402402{
    403403    switch (relation) {
     
    410410    case CSSSelector::IndirectAdjacent:
    411411        return FragmentRelation::IndirectAdjacent;
    412     case CSSSelector::SubSelector:
     412    case CSSSelector::Subselector:
    413413    case CSSSelector::ShadowDescendant:
    414414    case CSSSelector::ShadowPseudo:
     
    999999        }
    10001000
    1001         CSSSelector::Relation relation = selector->relation();
    1002         if (relation == CSSSelector::SubSelector)
     1001        auto relation = selector->relation();
     1002        if (relation == CSSSelector::Subselector)
    10031003            continue;
    10041004
  • trunk/Source/WebCore/dom/SelectorQuery.cpp

    r207396 r207536  
    7171            return IdMatchingType::Filter;
    7272        }
    73         if (selector->relation() != CSSSelector::SubSelector)
     73        if (selector->relation() != CSSSelector::Subselector)
    7474            inRightmost = false;
    7575    }
     
    205205        if (canBeUsedForIdFastPath(*selector))
    206206            return selector;
    207         if (selector->relation() != CSSSelector::SubSelector)
     207        if (selector->relation() != CSSSelector::Subselector)
    208208            break;
    209209    }
     
    257257    do {
    258258        ASSERT(!canBeUsedForIdFastPath(*selector));
    259         if (selector->relation() != CSSSelector::SubSelector)
     259        if (selector->relation() != CSSSelector::Subselector)
    260260            break;
    261261        selector = selector->tagHistory();
     
    275275            }
    276276        }
    277         if (selector->relation() == CSSSelector::SubSelector)
     277        if (selector->relation() == CSSSelector::Subselector)
    278278            continue;
    279279        if (selector->relation() == CSSSelector::DirectAdjacent || selector->relation() == CSSSelector::IndirectAdjacent)
Note: See TracChangeset for help on using the changeset viewer.