Move security origin filtering for getMatchedCSSRules out of StyleResolver
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Dec 2017 23:58:39 +0000 (23:58 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Dec 2017 23:58:39 +0000 (23:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180468

Reviewed by Zalan Bujtas.

The non-standard getMatchedCSSRules API should not return rules from stylesheets in different security origins.
To implement this we currently have lots of invasive code in StyleResolver, RuleSets and ElementRuleCollector
basically passing around a bit. This also makes RuleSets document specific blocking optimizations.

This patches replaces the mechanism with a bit in StyleRule which is much simpler.

* css/DocumentRuleSets.cpp:
(WebCore::makeRuleSet):
* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::collectMatchingRulesForList):
* css/ElementRuleCollector.h:
(WebCore::ElementRuleCollector::setPseudoStyleRequest):
(WebCore::ElementRuleCollector::setSameOriginOnly): Deleted.
* css/RuleFeature.cpp:
(WebCore::RuleFeatureSet::collectFeatures):
* css/RuleFeature.h:
(WebCore::RuleFeature::RuleFeature):
* css/RuleSet.cpp:
(WebCore::RuleData::RuleData):
(WebCore::RuleSet::addRule):
(WebCore::RuleSet::addChildRules):
(WebCore::RuleSet::addRulesFromSheet):
(WebCore::RuleSet::addStyleRule):
* css/RuleSet.h:
(WebCore::RuleData::linkMatchType const):
(WebCore::RuleData::hasDocumentSecurityOrigin const): Deleted.
* css/StyleResolver.cpp:
(WebCore::StyleResolver::pseudoStyleRulesForElement):
* css/StyleResolver.h:
* css/StyleRule.cpp:
(WebCore::StyleRule::StyleRule):
(WebCore::StyleRule::createForSplitting):
(WebCore::StyleRule::splitIntoMultipleRulesWithMaximumSelectorComponentCount const):
(WebCore::StyleRule::create): Deleted.
* css/StyleRule.h:
(WebCore::StyleRuleBase::StyleRuleBase):
(WebCore::StyleRuleBase::hasDocumentSecurityOrigin const):

    Add a bit.

* css/parser/CSSParser.cpp:
(WebCore::CSSParserContext::CSSParserContext):

    Include hasDocumentSecurityOrigin bit to parser context. This means that a stylesheet data structures
    can't be shared between a contexts where this differs. This likely very rare in practice.

(WebCore::operator==):
* css/parser/CSSParserImpl.cpp:
(WebCore::CSSParserImpl::consumeStyleRule):
* css/parser/CSSParserMode.h:
(WebCore::CSSParserContextHash::hash):
* editing/EditingStyle.cpp:
(WebCore::EditingStyle::mergeStyleFromRules):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::getMatchedCSSRules const):

    Filter out rules from different security origin after getting them from style resolver.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225650 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/css/DocumentRuleSets.cpp
Source/WebCore/css/ElementRuleCollector.cpp
Source/WebCore/css/ElementRuleCollector.h
Source/WebCore/css/RuleFeature.cpp
Source/WebCore/css/RuleFeature.h
Source/WebCore/css/RuleSet.cpp
Source/WebCore/css/RuleSet.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/css/StyleRule.cpp
Source/WebCore/css/StyleRule.h
Source/WebCore/css/parser/CSSParser.cpp
Source/WebCore/css/parser/CSSParserImpl.cpp
Source/WebCore/css/parser/CSSParserMode.h
Source/WebCore/editing/EditingStyle.cpp
Source/WebCore/page/DOMWindow.cpp

index 33811e3..43b7064 100644 (file)
@@ -1,3 +1,68 @@
+2017-12-07  Antti Koivisto  <antti@apple.com>
+
+        Move security origin filtering for getMatchedCSSRules out of StyleResolver
+        https://bugs.webkit.org/show_bug.cgi?id=180468
+
+        Reviewed by Zalan Bujtas.
+
+        The non-standard getMatchedCSSRules API should not return rules from stylesheets in different security origins.
+        To implement this we currently have lots of invasive code in StyleResolver, RuleSets and ElementRuleCollector
+        basically passing around a bit. This also makes RuleSets document specific blocking optimizations.
+
+        This patches replaces the mechanism with a bit in StyleRule which is much simpler.
+
+        * css/DocumentRuleSets.cpp:
+        (WebCore::makeRuleSet):
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+        * css/ElementRuleCollector.h:
+        (WebCore::ElementRuleCollector::setPseudoStyleRequest):
+        (WebCore::ElementRuleCollector::setSameOriginOnly): Deleted.
+        * css/RuleFeature.cpp:
+        (WebCore::RuleFeatureSet::collectFeatures):
+        * css/RuleFeature.h:
+        (WebCore::RuleFeature::RuleFeature):
+        * css/RuleSet.cpp:
+        (WebCore::RuleData::RuleData):
+        (WebCore::RuleSet::addRule):
+        (WebCore::RuleSet::addChildRules):
+        (WebCore::RuleSet::addRulesFromSheet):
+        (WebCore::RuleSet::addStyleRule):
+        * css/RuleSet.h:
+        (WebCore::RuleData::linkMatchType const):
+        (WebCore::RuleData::hasDocumentSecurityOrigin const): Deleted.
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::pseudoStyleRulesForElement):
+        * css/StyleResolver.h:
+        * css/StyleRule.cpp:
+        (WebCore::StyleRule::StyleRule):
+        (WebCore::StyleRule::createForSplitting):
+        (WebCore::StyleRule::splitIntoMultipleRulesWithMaximumSelectorComponentCount const):
+        (WebCore::StyleRule::create): Deleted.
+        * css/StyleRule.h:
+        (WebCore::StyleRuleBase::StyleRuleBase):
+        (WebCore::StyleRuleBase::hasDocumentSecurityOrigin const):
+
+            Add a bit.
+
+        * css/parser/CSSParser.cpp:
+        (WebCore::CSSParserContext::CSSParserContext):
+
+            Include hasDocumentSecurityOrigin bit to parser context. This means that a stylesheet data structures
+            can't be shared between a contexts where this differs. This likely very rare in practice.
+
+        (WebCore::operator==):
+        * css/parser/CSSParserImpl.cpp:
+        (WebCore::CSSParserImpl::consumeStyleRule):
+        * css/parser/CSSParserMode.h:
+        (WebCore::CSSParserContextHash::hash):
+        * editing/EditingStyle.cpp:
+        (WebCore::EditingStyle::mergeStyleFromRules):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::getMatchedCSSRules const):
+
+            Filter out rules from different security origin after getting them from style resolver.
+
 2017-12-07  Zalan Bujtas  <zalan@apple.com>
 
         AX: Document::existingAXObjectCache() should always return the existing AXObjectCache.
index 742298f..1f4a2c8 100644 (file)
@@ -114,7 +114,7 @@ static std::unique_ptr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
         return nullptr;
     auto ruleSet = std::make_unique<RuleSet>();
     for (size_t i = 0; i < size; ++i)
-        ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
+        ruleSet->addRule(rules[i].rule, rules[i].selectorIndex);
     ruleSet->shrinkToFit();
     return ruleSet;
 }
index 09c14ed..ff3a771 100644 (file)
@@ -476,10 +476,6 @@ void ElementRuleCollector::collectMatchingRulesForList(const RuleSet::RuleDataVe
         if (properties && properties->isEmpty() && !matchRequest.includeEmptyRules)
             continue;
 
-        // FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed.
-        if (m_sameOriginOnly && !ruleData.hasDocumentSecurityOrigin())
-            continue;
-
         unsigned specificity;
         if (ruleMatches(ruleData, specificity))
             addMatchedRule(ruleData, specificity, matchRequest.styleScopeOrdinal, ruleRange);
index 8106d23..4528a0e 100644 (file)
@@ -54,7 +54,6 @@ public:
 
     void setMode(SelectorChecker::Mode mode) { m_mode = mode; }
     void setPseudoStyleRequest(const PseudoStyleRequest& request) { m_pseudoStyleRequest = request; }
-    void setSameOriginOnly(bool f) { m_sameOriginOnly = f; } 
     void setMedium(const MediaQueryEvaluator* medium) { m_isPrintStyle = medium->mediaTypeMatchSpecific("print"); }
 
     bool hasAnyMatchingRules(const RuleSet*);
@@ -97,7 +96,6 @@ private:
 
     bool m_isPrintStyle { false };
     PseudoStyleRequest m_pseudoStyleRequest { NOPSEUDO };
-    bool m_sameOriginOnly { false };
     SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
     bool m_isMatchingSlottedPseudoElements { false };
     bool m_isMatchingHostPseudoClass { false };
index 133de48..2c0c957 100644 (file)
@@ -96,14 +96,14 @@ void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
     SelectorFeatures selectorFeatures;
     recursivelyCollectFeaturesFromSelector(selectorFeatures, *ruleData.selector());
     if (selectorFeatures.hasSiblingSelector)
-        siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+        siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
     if (ruleData.containsUncommonAttributeSelector())
-        uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+        uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
     for (auto& className : selectorFeatures.classesMatchingAncestors) {
         auto addResult = ancestorClassRules.ensure(className, [] {
             return std::make_unique<Vector<RuleFeature>>();
         });
-        addResult.iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+        addResult.iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
     }
     for (auto* selector : selectorFeatures.attributeSelectorsMatchingAncestors) {
         // Hashing by attributeCanonicalLocalName makes this HTML specific.
@@ -111,7 +111,7 @@ void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
             return std::make_unique<AttributeRules>();
         });
         auto& rules = *addResult.iterator->value;
-        rules.features.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+        rules.features.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
         // Deduplicate selectors.
         rules.selectors.add(makeAttributeSelectorKey(*selector), selector);
     }
index d240a85..2b11693 100644 (file)
@@ -34,15 +34,13 @@ class RuleData;
 class StyleRule;
 
 struct RuleFeature {
-    RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
+    RuleFeature(StyleRule* rule, unsigned selectorIndex)
         : rule(rule)
         , selectorIndex(selectorIndex)
-        , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) 
-    { 
+    {
     }
     StyleRule* rule;
     unsigned selectorIndex;
-    bool hasDocumentSecurityOrigin;
 };
 
 struct RuleFeatureSet {
index f188ae0..f01e92f 100644 (file)
@@ -148,10 +148,9 @@ static inline PropertyWhitelistType determinePropertyWhitelistType(const CSSSele
     return PropertyWhitelistNone;
 }
 
-RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, AddRuleFlags addRuleFlags)
+RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position)
     : m_rule(rule)
     , m_selectorIndex(selectorIndex)
-    , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin)
     , m_position(position)
     , m_matchBasedOnRuleHash(static_cast<unsigned>(computeMatchBasedOnRuleHash(*selector())))
     , m_canMatchPseudoElement(selectorCanMatchPseudoElement(*selector()))
@@ -202,9 +201,9 @@ static bool isHostSelectorMatchingInShadowTree(const CSSSelector& startSelector)
     return leftmostSelector->match() == CSSSelector::PseudoClass && leftmostSelector->pseudoClassType() == CSSSelector::PseudoClassHost;
 }
 
-void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addRuleFlags)
+void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex)
 {
-    RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags);
+    RuleData ruleData(rule, selectorIndex, m_ruleCount++);
     m_features.collectFeatures(ruleData);
 
     unsigned classBucketSize = 0;
@@ -360,17 +359,17 @@ void RuleSet::addPageRule(StyleRulePage* rule)
     m_pageRules.append(rule);
 }
 
-void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, bool hasDocumentSecurityOrigin, bool isInitiatingElementInUserAgentShadowTree, AddRuleFlags addRuleFlags)
+void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, bool isInitiatingElementInUserAgentShadowTree)
 {
     for (auto& rule : rules) {
         if (is<StyleRule>(*rule))
-            addStyleRule(downcast<StyleRule>(rule.get()), addRuleFlags);
+            addStyleRule(downcast<StyleRule>(rule.get()));
         else if (is<StyleRulePage>(*rule))
             addPageRule(downcast<StyleRulePage>(rule.get()));
         else if (is<StyleRuleMedia>(*rule)) {
             auto& mediaRule = downcast<StyleRuleMedia>(*rule);
             if ((!mediaRule.mediaQueries() || medium.evaluate(*mediaRule.mediaQueries(), resolver)))
-                addChildRules(mediaRule.childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags);
+                addChildRules(mediaRule.childRules(), medium, resolver, isInitiatingElementInUserAgentShadowTree);
         } else if (is<StyleRuleFontFace>(*rule) && resolver) {
             // Add this font face to our set.
             resolver->document().fontSelector().addFontFaceRule(downcast<StyleRuleFontFace>(*rule.get()), isInitiatingElementInUserAgentShadowTree);
@@ -378,7 +377,7 @@ void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const Me
         } else if (is<StyleRuleKeyframes>(*rule) && resolver)
             resolver->addKeyframeStyle(downcast<StyleRuleKeyframes>(*rule));
         else if (is<StyleRuleSupports>(*rule) && downcast<StyleRuleSupports>(*rule).conditionIsSupported())
-            addChildRules(downcast<StyleRuleSupports>(*rule).childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags);
+            addChildRules(downcast<StyleRuleSupports>(*rule).childRules(), medium, resolver, isInitiatingElementInUserAgentShadowTree);
 #if ENABLE(CSS_DEVICE_ADAPTATION)
         else if (is<StyleRuleViewport>(*rule) && resolver) {
             resolver->viewportStyleResolver()->addViewportRule(downcast<StyleRuleViewport>(rule.get()));
@@ -394,22 +393,19 @@ void RuleSet::addRulesFromSheet(StyleSheetContents& sheet, const MediaQueryEvalu
             addRulesFromSheet(*rule->styleSheet(), medium, resolver);
     }
 
-    bool hasDocumentSecurityOrigin = resolver && resolver->document().securityOrigin().canRequest(sheet.baseURL());
-    AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0));
-
     // FIXME: Skip Content Security Policy check when stylesheet is in a user agent shadow tree.
     // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
     bool isInitiatingElementInUserAgentShadowTree = false;
-    addChildRules(sheet.childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags);
+    addChildRules(sheet.childRules(), medium, resolver, isInitiatingElementInUserAgentShadowTree);
 
     if (m_autoShrinkToFitEnabled)
         shrinkToFit();
 }
 
-void RuleSet::addStyleRule(StyleRule* rule, AddRuleFlags addRuleFlags)
+void RuleSet::addStyleRule(StyleRule* rule)
 {
     for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = rule->selectorList().indexOfNextSelectorAfter(selectorIndex))
-        addRule(rule, selectorIndex, addRuleFlags);
+        addRule(rule, selectorIndex);
 }
 
 bool RuleSet::hasShadowPseudoElementRules() const
index f902add..f901cfa 100644 (file)
 
 namespace WebCore {
 
-enum AddRuleFlags {
-    RuleHasNoSpecialState         = 0,
-    RuleHasDocumentSecurityOrigin = 1,
-};
-    
 enum PropertyWhitelistType {
     PropertyWhitelistNone   = 0,
     PropertyWhitelistMarker,
@@ -64,7 +59,7 @@ class RuleData {
 public:
     static const unsigned maximumSelectorComponentCount = 8192;
 
-    RuleData(StyleRule*, unsigned selectorIndex, unsigned position, AddRuleFlags);
+    RuleData(StyleRule*, unsigned selectorIndex, unsigned position);
 
     unsigned position() const { return m_position; }
     StyleRule* rule() const { return m_rule.get(); }
@@ -75,7 +70,6 @@ public:
     MatchBasedOnRuleHash matchBasedOnRuleHash() const { return static_cast<MatchBasedOnRuleHash>(m_matchBasedOnRuleHash); }
     bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
     unsigned linkMatchType() const { return m_linkMatchType; }
-    bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; }
     PropertyWhitelistType propertyWhitelistType() const { return static_cast<PropertyWhitelistType>(m_propertyWhitelistType); }
     const SelectorFilter::Hashes& descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
 
@@ -102,7 +96,6 @@ public:
 private:
     RefPtr<StyleRule> m_rule;
     unsigned m_selectorIndex : 13;
-    unsigned m_hasDocumentSecurityOrigin : 1;
     // This number was picked fairly arbitrarily. We can probably lower it if we need to.
     // Some simple testing showed <100,000 RuleData's on large sites.
     unsigned m_position : 18;
@@ -158,8 +151,8 @@ public:
 
     void addRulesFromSheet(StyleSheetContents&, const MediaQueryEvaluator&, StyleResolver* = 0);
 
-    void addStyleRule(StyleRule*, AddRuleFlags);
-    void addRule(StyleRule*, unsigned selectorIndex, AddRuleFlags);
+    void addStyleRule(StyleRule*);
+    void addRule(StyleRule*, unsigned selectorIndex);
     void addPageRule(StyleRulePage*);
     void addToRuleSet(const AtomicString& key, AtomRuleMap&, const RuleData&);
     void shrinkToFit();
@@ -188,7 +181,7 @@ public:
     bool hasHostPseudoClassRulesMatchingInShadowTree() const { return m_hasHostPseudoClassRulesMatchingInShadowTree; }
 
 private:
-    void addChildRules(const Vector<RefPtr<StyleRuleBase>>&, const MediaQueryEvaluator& medium, StyleResolver*, bool hasDocumentSecurityOrigin, bool isInitiatingElementInUserAgentShadowTree, AddRuleFlags);
+    void addChildRules(const Vector<RefPtr<StyleRuleBase>>&, const MediaQueryEvaluator& medium, StyleResolver*, bool isInitiatingElementInUserAgentShadowTree);
 
     AtomRuleMap m_idRules;
     AtomRuleMap m_classRules;
index e6ec0aa..13b0a4e 100644 (file)
@@ -1132,12 +1132,8 @@ Vector<RefPtr<StyleRule>> StyleResolver::pseudoStyleRulesForElement(const Elemen
             collector.matchUserRules(rulesToInclude & EmptyCSSRules);
     }
 
-    if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules)) {
-        collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules));
-
-        // Check the rules in author sheets.
+    if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules))
         collector.matchAuthorRules(rulesToInclude & EmptyCSSRules);
-    }
 
     return collector.matchedRuleList();
 }
index 738b050..82db1f6 100644 (file)
@@ -167,8 +167,7 @@ public:
         UAAndUserCSSRules   = 1 << 1,
         AuthorCSSRules      = 1 << 2,
         EmptyCSSRules       = 1 << 3,
-        CrossOriginCSSRules = 1 << 4,
-        AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
+        AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules,
         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
     };
     Vector<RefPtr<StyleRule>> styleRulesForElement(const Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
index 1c53bd4..86a5c2b 100644 (file)
@@ -181,8 +181,8 @@ unsigned StyleRule::averageSizeInBytes()
     return sizeof(StyleRule) + sizeof(CSSSelector) + StyleProperties::averageSizeInBytes();
 }
 
-StyleRule::StyleRule(Ref<StylePropertiesBase>&& properties)
-    : StyleRuleBase(Style)
+StyleRule::StyleRule(Ref<StylePropertiesBase>&& properties, bool hasDocumentSecurityOrigin)
+    : StyleRuleBase(Style, hasDocumentSecurityOrigin)
     , m_properties(WTFMove(properties))
 {
 }
@@ -210,14 +210,14 @@ MutableStyleProperties& StyleRule::mutableProperties()
     return downcast<MutableStyleProperties>(m_properties.get());
 }
 
-Ref<StyleRule> StyleRule::create(const Vector<const CSSSelector*>& selectors, Ref<StyleProperties>&& properties)
+Ref<StyleRule> StyleRule::createForSplitting(const Vector<const CSSSelector*>& selectors, Ref<StyleProperties>&& properties, bool hasDocumentSecurityOrigin)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!selectors.isEmpty());
     CSSSelector* selectorListArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectors.size()));
     for (unsigned i = 0; i < selectors.size(); ++i)
         new (NotNull, &selectorListArray[i]) CSSSelector(*selectors.at(i));
     selectorListArray[selectors.size() - 1].setLastInSelectorList();
-    auto rule = StyleRule::create(WTFMove(properties));
+    auto rule = StyleRule::create(WTFMove(properties), hasDocumentSecurityOrigin);
     rule.get().parserAdoptSelectorArray(selectorListArray);
     return rule;
 }
@@ -235,7 +235,7 @@ Vector<RefPtr<StyleRule>> StyleRule::splitIntoMultipleRulesWithMaximumSelectorCo
             componentsInThisSelector.append(component);
 
         if (componentsInThisSelector.size() + componentsSinceLastSplit.size() > maxCount && !componentsSinceLastSplit.isEmpty()) {
-            rules.append(create(componentsSinceLastSplit, const_cast<StyleProperties&>(properties())));
+            rules.append(createForSplitting(componentsSinceLastSplit, const_cast<StyleProperties&>(properties()), hasDocumentSecurityOrigin()));
             componentsSinceLastSplit.clear();
         }
 
@@ -243,7 +243,7 @@ Vector<RefPtr<StyleRule>> StyleRule::splitIntoMultipleRulesWithMaximumSelectorCo
     }
 
     if (!componentsSinceLastSplit.isEmpty())
-        rules.append(create(componentsSinceLastSplit, const_cast<StyleProperties&>(properties())));
+        rules.append(createForSplitting(componentsSinceLastSplit, const_cast<StyleProperties&>(properties()), hasDocumentSecurityOrigin()));
 
     return rules;
 }
index 398e3b9..dfcf19e 100644 (file)
@@ -86,31 +86,39 @@ public:
     RefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
 
 protected:
-    StyleRuleBase(Type type)
+    StyleRuleBase(Type type, bool hasDocumentSecurityOrigin = false)
         : m_type(type)
-        { }
+        , m_hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
+    {
+    }
 
     StyleRuleBase(const StyleRuleBase& o)
         : WTF::RefCountedBase()
         , m_type(o.m_type)
-        { }
+        , m_hasDocumentSecurityOrigin(o.m_hasDocumentSecurityOrigin)
+    {
+    }
 
     ~StyleRuleBase() = default;
 
+    bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; }
+
 private:
     WEBCORE_EXPORT void destroy();
     
     RefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
 
     unsigned m_type : 5;
+    // This is only needed to support getMatchedCSSRules.
+    unsigned m_hasDocumentSecurityOrigin : 1;
 };
 
 class StyleRule final : public StyleRuleBase {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties)
+    static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties, bool hasDocumentSecurityOrigin)
     {
-        return adoptRef(*new StyleRule(WTFMove(properties)));
+        return adoptRef(*new StyleRule(WTFMove(properties), hasDocumentSecurityOrigin));
     }
     
     ~StyleRule();
@@ -121,6 +129,8 @@ public:
     MutableStyleProperties& mutableProperties();
     const StyleProperties* propertiesWithoutDeferredParsing() const;
 
+    using StyleRuleBase::hasDocumentSecurityOrigin;
+
     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
     void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); }
@@ -132,10 +142,10 @@ public:
     static unsigned averageSizeInBytes();
 
 private:
-    StyleRule(Ref<StylePropertiesBase>&&);
+    StyleRule(Ref<StylePropertiesBase>&&, bool hasDocumentSecurityOrigin);
     StyleRule(const StyleRule&);
 
-    static Ref<StyleRule> create(const Vector<const CSSSelector*>&, Ref<StyleProperties>&&);
+    static Ref<StyleRule> createForSplitting(const Vector<const CSSSelector*>&, Ref<StyleProperties>&&, bool hasDocumentSecurityOrigin);
 
     mutable Ref<StylePropertiesBase> m_properties;
     CSSSelectorList m_selectorList;
index 843c404..6578e51 100644 (file)
@@ -72,12 +72,13 @@ CSSParserContext::CSSParserContext(CSSParserMode mode, const URL& baseURL)
 #endif
 }
 
-CSSParserContext::CSSParserContext(Document& document, const URL& baseURL, const String& charset)
-    : baseURL(baseURL.isNull() ? document.baseURL() : baseURL)
+CSSParserContext::CSSParserContext(Document& document, const URL& sheetBaseURL, const String& charset)
+    : baseURL(sheetBaseURL.isNull() ? document.baseURL() : sheetBaseURL)
     , charset(charset)
     , mode(document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode)
     , isHTMLDocument(document.isHTMLDocument())
     , cssGridLayoutEnabled(document.isCSSGridLayoutEnabled())
+    , hasDocumentSecurityOrigin(document.securityOrigin().canRequest(baseURL))
 {
     needsSiteSpecificQuirks = document.settings().needsSiteSpecificQuirks();
     enforcesCSSMIMETypeInNoQuirksMode = document.settings().enforceCSSMIMETypeInNoQuirksMode();
@@ -111,7 +112,8 @@ bool operator==(const CSSParserContext& a, const CSSParserContext& b)
         && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled
         && a.constantPropertiesEnabled == b.constantPropertiesEnabled
         && a.conicGradientsEnabled == b.conicGradientsEnabled
-        && a.deferredCSSParserEnabled == b.deferredCSSParserEnabled;
+        && a.deferredCSSParserEnabled == b.deferredCSSParserEnabled
+        && a.hasDocumentSecurityOrigin == b.hasDocumentSecurityOrigin;
 }
 
 CSSParser::CSSParser(const CSSParserContext& context)
index 695780c..6e841f9 100644 (file)
@@ -738,14 +738,14 @@ RefPtr<StyleRule> CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, C
         CSSParserTokenRange blockCopy = block;
         blockCopy.consumeWhitespace();
         if (!blockCopy.atEnd()) {
-            rule = StyleRule::create(createDeferredStyleProperties(block));
+            rule = StyleRule::create(createDeferredStyleProperties(block), m_context.hasDocumentSecurityOrigin);
             rule->wrapperAdoptSelectorList(selectorList);
             return rule;
         }
     }
 
     consumeDeclarationList(block, StyleRule::Style);
-    rule = StyleRule::create(createStyleProperties(m_parsedProperties, m_context.mode));
+    rule = StyleRule::create(createStyleProperties(m_parsedProperties, m_context.mode), m_context.hasDocumentSecurityOrigin);
     rule->wrapperAdoptSelectorList(selectorList);
     return rule;
 }
index fcb5794..d3a2020 100644 (file)
@@ -107,6 +107,8 @@ public:
     bool constantPropertiesEnabled { false };
     bool conicGradientsEnabled { false };
     bool deferredCSSParserEnabled { false };
+    // This is only needed to support getMatchedCSSRules.
+    bool hasDocumentSecurityOrigin { false };
 
     URL completeURL(const String& url) const
     {
@@ -141,7 +143,8 @@ struct CSSParserContextHash {
             & key.springTimingFunctionEnabled               << 7
             & key.conicGradientsEnabled                     << 8
             & key.deferredCSSParserEnabled                  << 9
-            & key.mode                                      << 10;
+            & key.hasDocumentSecurityOrigin                 << 10
+            & key.mode                                      << 11;
         hash ^= WTF::intHash(bits);
         return hash;
     }
index b88737d..5a1dbef 100644 (file)
@@ -1269,7 +1269,7 @@ static Ref<MutableStyleProperties> styleFromMatchedRulesForElement(Element& elem
 void EditingStyle::mergeStyleFromRules(StyledElement& element)
 {
     RefPtr<MutableStyleProperties> styleFromMatchedRules = styleFromMatchedRulesForElement(element,
-        StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules);
+        StyleResolver::AuthorCSSRules);
     // Styles from the inline style declaration, held in the variable "style", take precedence 
     // over those from matched rules.
     if (m_mutableStyle)
index 4101ebb..b73348f 100644 (file)
@@ -1482,8 +1482,6 @@ RefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const String
     unsigned rulesToInclude = StyleResolver::AuthorCSSRules;
     if (!authorOnly)
         rulesToInclude |= StyleResolver::UAAndUserCSSRules;
-    if (m_frame->settings().crossOriginCheckInGetMatchedCSSRulesDisabled())
-        rulesToInclude |= StyleResolver::CrossOriginCSSRules;
 
     PseudoId pseudoId = CSSSelector::pseudoId(pseudoType);
 
@@ -1491,9 +1489,17 @@ RefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const String
     if (matchedRules.isEmpty())
         return nullptr;
 
+    bool allowCrossOrigin = m_frame->settings().crossOriginCheckInGetMatchedCSSRulesDisabled();
+
     RefPtr<StaticCSSRuleList> ruleList = StaticCSSRuleList::create();
-    for (auto& rule : matchedRules)
+    for (auto& rule : matchedRules) {
+        if (!allowCrossOrigin && !rule->hasDocumentSecurityOrigin())
+            continue;
         ruleList->rules().append(rule->createCSSOMWrapper());
+    }
+
+    if (ruleList->rules().isEmpty())
+        return nullptr;
 
     return ruleList;
 }