Changeset 199844 in webkit


Ignore:
Timestamp:
Apr 21, 2016 4:28:48 PM (8 years ago)
Author:
Chris Dumez
Message:

Element::idForStyleResolution() is a foot-gun
https://bugs.webkit.org/show_bug.cgi?id=156852

Reviewed by Darin Adler.

Element::idForStyleResolution() is a foot-gun. It requires the caller to check
Element::hasID() first or it may end up crashing when dereferencing elementData()
(e.g. see Bug 156806).

This patch updates Element::idForStyleResolution() to return nullAtom is the
Element does not have an ID. I did not see a performance impact on Speedometer,
Dromaeo DOM Core, Dromaeo CSS Selectors and our local performanceTests/.

  • css/ElementRuleCollector.cpp:

(WebCore::ElementRuleCollector::collectMatchingRules):

  • css/SelectorChecker.cpp:

(WebCore::SelectorChecker::checkOne):

  • css/SelectorFilter.cpp:

(WebCore::collectElementIdentifierHashes):

  • dom/Element.h:

(WebCore::Element::idForStyleResolution):

  • rendering/RenderBlockFlow.cpp:

(WebCore::needsAppleMailPaginationQuirk):

  • rendering/RenderTreeAsText.cpp:

(WebCore::writeRenderRegionList):

  • style/StyleSharingResolver.cpp:

(WebCore::Style::SharingResolver::canShareStyleWithElement):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r199843 r199844  
     12016-04-21  Chris Dumez  <cdumez@apple.com>
     2
     3        Element::idForStyleResolution() is a foot-gun
     4        https://bugs.webkit.org/show_bug.cgi?id=156852
     5
     6        Reviewed by Darin Adler.
     7
     8        Element::idForStyleResolution() is a foot-gun. It requires the caller to check
     9        Element::hasID() first or it may end up crashing when dereferencing elementData()
     10        (e.g. see Bug 156806).
     11
     12        This patch updates Element::idForStyleResolution() to return nullAtom is the
     13        Element does not have an ID. I did not see a performance impact on Speedometer,
     14        Dromaeo DOM Core, Dromaeo CSS Selectors and our local performanceTests/.
     15
     16        * css/ElementRuleCollector.cpp:
     17        (WebCore::ElementRuleCollector::collectMatchingRules):
     18        * css/SelectorChecker.cpp:
     19        (WebCore::SelectorChecker::checkOne):
     20        * css/SelectorFilter.cpp:
     21        (WebCore::collectElementIdentifierHashes):
     22        * dom/Element.h:
     23        (WebCore::Element::idForStyleResolution):
     24        * rendering/RenderBlockFlow.cpp:
     25        (WebCore::needsAppleMailPaginationQuirk):
     26        * rendering/RenderTreeAsText.cpp:
     27        (WebCore::writeRenderRegionList):
     28        * style/StyleSharingResolver.cpp:
     29        (WebCore::Style::SharingResolver::canShareStyleWithElement):
     30
    1312016-04-21  Brady Eidson  <beidson@apple.com>
    232
  • trunk/Source/WebCore/css/ElementRuleCollector.cpp

    r199291 r199844  
    154154    // We need to collect the rules for id, class, tag, and everything else into a buffer and
    155155    // then sort the buffer.
    156     if (m_element.hasID())
    157         collectMatchingRulesForList(matchRequest.ruleSet->idRules(m_element.idForStyleResolution().impl()), matchRequest, ruleRange);
     156    auto& id = m_element.idForStyleResolution();
     157    if (!id.isNull())
     158        collectMatchingRulesForList(matchRequest.ruleSet->idRules(*id.impl()), matchRequest, ruleRange);
    158159    if (m_element.hasClass()) {
    159160        for (size_t i = 0; i < m_element.classNames().size(); ++i)
  • trunk/Source/WebCore/css/RuleSet.h

    r197165 r199844  
    175175    const RuleFeatureSet& features() const { return m_features; }
    176176
    177     const RuleDataVector* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); }
     177    const RuleDataVector* idRules(AtomicStringImpl& key) const { return m_idRules.get(&key); }
    178178    const RuleDataVector* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); }
    179179    const RuleDataVector* tagRules(AtomicStringImpl* key, bool isHTMLName) const;
  • trunk/Source/WebCore/css/SelectorChecker.cpp

    r199583 r199844  
    653653        return element.hasClass() && element.classNames().contains(selector.value());
    654654
    655     if (selector.match() == CSSSelector::Id)
    656         return element.hasID() && element.idForStyleResolution() == selector.value();
     655    if (selector.match() == CSSSelector::Id) {
     656        ASSERT(!selector.value().isNull());
     657        return element.idForStyleResolution() == selector.value();
     658    }
    657659
    658660    if (selector.isAttributeSelector()) {
  • trunk/Source/WebCore/css/SelectorFilter.cpp

    r194762 r199844  
    4444    identifierHashes.append(tagLowercaseLocalName.impl()->existingHash() * TagNameSalt);
    4545
    46     if (element->hasID())
    47         identifierHashes.append(element->idForStyleResolution().impl()->existingHash() * IdAttributeSalt);
     46    auto& id = element->idForStyleResolution();
     47    if (!id.isNull())
     48        identifierHashes.append(id.impl()->existingHash() * IdAttributeSalt);
    4849    const StyledElement* styledElement = element->isStyledElement() ? static_cast<const StyledElement*>(element) : 0;
    4950    if (styledElement && styledElement->hasClass()) {
  • trunk/Source/WebCore/dom/Element.h

    r199154 r199844  
    665665inline const AtomicString& Element::idForStyleResolution() const
    666666{
    667     ASSERT(hasID());
    668     return elementData()->idForStyleResolution();
     667    return hasID() ? elementData()->idForStyleResolution() : nullAtom;
    669668}
    670669
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r199784 r199844  
    16441644        return false;
    16451645
    1646     if (renderer.element() && renderer.element()->hasID() && renderer.element()->idForStyleResolution() == "messageContentContainer")
     1646    if (renderer.element() && renderer.element()->idForStyleResolution() == "messageContentContainer")
    16471647        return true;
    16481648
  • trunk/Source/WebCore/rendering/RenderTreeAsText.cpp

    r198859 r199844  
    691691            ts << " {" << tagName.toString() << "}";
    692692
    693             if (generatingElement->hasID())
    694                 ts << " #" << generatingElement->idForStyleResolution();
     693            auto& generatingElementId = generatingElement->idForStyleResolution();
     694            if (!generatingElementId.isNull())
     695                ts << " #" << generatingElementId;
    695696
    696697            if (isRenderNamedFlowFragment)
  • trunk/Source/WebCore/style/StyleSharingResolver.cpp

    r199584 r199844  
    8989        return nullptr;
    9090    // Ids stop style sharing if they show up in the stylesheets.
    91     if (element.hasID() && m_ruleSets.features().idsInRules.contains(element.idForStyleResolution().impl()))
     91    auto& id = element.idForStyleResolution();
     92    if (!id.isNull() && m_ruleSets.features().idsInRules.contains(id.impl()))
    9293        return nullptr;
    9394    if (parentElementPreventsSharing(parentElement))
     
    238239        return false;
    239240
    240     if (candidateElement.hasID() && m_ruleSets.features().idsInRules.contains(candidateElement.idForStyleResolution().impl()))
     241    auto& candidateElementId = candidateElement.idForStyleResolution();
     242    if (!candidateElementId.isNull() && m_ruleSets.features().idsInRules.contains(candidateElementId.impl()))
    241243        return false;
    242244
Note: See TracChangeset for help on using the changeset viewer.