Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Unified Diff: Source/core/css/ElementRuleCollector.cpp

Issue 49093005: Fix memory error during selector matching due to getMatchedCSSRules. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/css/ElementRuleCollector.h ('k') | Source/core/css/resolver/StyleResolver.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/css/ElementRuleCollector.cpp
diff --git a/Source/core/css/ElementRuleCollector.cpp b/Source/core/css/ElementRuleCollector.cpp
index deff32a41630b5914d77b31d4d7a15aa6c1b6c7d..860f3675153610962392e527b3fc8b6f165bb39f 100644
--- a/Source/core/css/ElementRuleCollector.cpp
+++ b/Source/core/css/ElementRuleCollector.cpp
@@ -31,6 +31,7 @@
#include "core/css/CSSRuleList.h"
#include "core/css/CSSSelector.h"
+#include "core/css/CSSStyleRule.h"
#include "core/css/SelectorCheckerFastPath.h"
#include "core/css/SiblingTraversalStrategies.h"
#include "core/css/StylePropertySet.h"
@@ -41,7 +42,7 @@
namespace WebCore {
ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context,
- const SelectorFilter& filter, RenderStyle* style)
+ const SelectorFilter& filter, RenderStyle* style, ShouldIncludeStyleSheetInCSSOMWrapper includeStyleSheet)
: m_context(context)
, m_selectorFilter(filter)
, m_style(style)
@@ -51,6 +52,7 @@ ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context,
, m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(context.parentNode()))
, m_sameOriginOnly(false)
, m_matchingUARules(false)
+ , m_includeStyleSheet(includeStyleSheet)
{ }
ElementRuleCollector::~ElementRuleCollector()
@@ -178,6 +180,46 @@ void ElementRuleCollector::collectMatchingRulesForRegion(const MatchRequest& mat
}
}
+
+static CSSStyleSheet* findStyleSheet(StyleEngine* styleEngine, StyleRule* rule)
+{
+ // FIXME: StyleEngine has a bunch of different accessors for StyleSheet lists, is this the only one we need to care about?
+ const Vector<RefPtr<CSSStyleSheet> >& stylesheets = styleEngine->activeAuthorStyleSheets();
+ for (size_t i = 0; i < stylesheets.size(); ++i) {
+ CSSStyleSheet* sheet = stylesheets[i].get();
+ for (unsigned j = 0; j < sheet->length(); ++j) {
+ CSSRule* cssRule = sheet->item(j);
+ if (cssRule->type() != CSSRule::STYLE_RULE)
+ continue;
+ CSSStyleRule* cssStyleRule = toCSSStyleRule(cssRule);
+ if (cssStyleRule->styleRule() == rule)
+ return sheet;
+ }
+ }
+ return 0;
+}
+
+void ElementRuleCollector::appendCSSOMWrapperForRule(StyleRule* rule)
+{
+ // FIXME: There should be no codepath that creates a CSSOMWrapper without a parent stylesheet or rule because
+ // then that codepath can lead to the CSSStyleSheet contents not getting correctly copied when the rule is modified
+ // through the wrapper (e.g. rule.selectorText="div"). Right now, the inspector uses the pointers for identity though,
+ // so calling CSSStyleSheet->willMutateRules breaks the inspector.
+ CSSStyleSheet* sheet = m_includeStyleSheet == IncludeStyleSheetInCSSOMWrapper ? findStyleSheet(m_context.element()->document().styleEngine(), rule) : 0;
+ // We need to call willMutateRules so that the StyleSheetContents are copy-on-writed before we create the CSSOMWrappers.
+ // Otherwise, if the sheet is modified through the regular CSSOM, the CSSOMWrappers created here won't be updated
+ // to point to the new copied StyleRules. An alternate solution would be to update all the CSSOMWrappers when
+ // the stylesheet is modified.
+ if (sheet) {
+ sheet->willMutateRules();
+ sheet->didMutateRules();
esprehn 2013/10/28 23:54:08 I think you're supposed to call didMutateRules at
ojan 2013/10/28 23:59:58 This function doesn't actually mutate the rules th
+ }
+ RefPtr<CSSRule> cssRule = rule->createCSSOMWrapper(sheet);
+ if (sheet)
+ sheet->registerExtraChildRuleCSSOMWrapper(cssRule);
+ ensureRuleList()->rules().append(cssRule);
+}
+
void ElementRuleCollector::sortAndTransferMatchedRules()
{
if (!m_matchedRules || m_matchedRules->isEmpty())
@@ -187,8 +229,9 @@ void ElementRuleCollector::sortAndTransferMatchedRules()
Vector<MatchedRule, 32>& matchedRules = *m_matchedRules;
if (m_mode == SelectorChecker::CollectingRules) {
- for (unsigned i = 0; i < matchedRules.size(); ++i)
- ensureRuleList()->rules().append(matchedRules[i].ruleData()->rule()->createCSSOMWrapper());
+ for (unsigned i = 0; i < matchedRules.size(); ++i) {
+ appendCSSOMWrapperForRule(matchedRules[i].ruleData()->rule());
+ }
return;
}
« no previous file with comments | « Source/core/css/ElementRuleCollector.h ('k') | Source/core/css/resolver/StyleResolver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698