aboutsummaryrefslogtreecommitdiff
path: root/src/css.cc
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2014-03-05 21:48:42 +0100
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2014-03-05 21:48:42 +0100
commit4ef5572a6256155b6213987f71f4d836cb891ffe (patch)
treed44acbc088d4d97421a5798b5184b0d2f144baf4 /src/css.cc
parent0b04276e8e917bad961e1178a959483a7aeb5620 (diff)
use a singe matchCache per CssContext
This fixes a crash with the following HTML: <head> <style type="text/css"> .first .second .third{ border-top-color:#aaa !important; } #n .a, .b{ color: #aaa !important; border:#bbb; } </style> </head> <body> <div id="submit" value="Submit" class="a"> jhu </div> </body> The problem is that CssSelectors can be shared between normal and !important rules. The matchCacheOffset was overwritten in that case causing the crash on access. noticed-by and test-case-by: corvid
Diffstat (limited to 'src/css.cc')
-rw-r--r--src/css.cc37
1 files changed, 19 insertions, 18 deletions
diff --git a/src/css.cc b/src/css.cc
index 4938a1cf..5bdf4fdb 100644
--- a/src/css.cc
+++ b/src/css.cc
@@ -399,9 +399,9 @@ void CssStyleSheet::addRule (CssRule *rule) {
}
if (ruleList) {
- rule->selector->setMatchCacheOffset (matchCacheOffset);
- matchCacheOffset += rule->selector->size ();
ruleList->insert (rule);
+ if (rule->selector->getRequiredMatchCache () > requiredMatchCache)
+ requiredMatchCache = rule->selector->getRequiredMatchCache ();
} else {
assert (top->getElement () == CssSimpleSelector::ELEMENT_NONE);
delete rule;
@@ -488,7 +488,7 @@ CssStyleSheet CssContext::userAgentSheet;
CssContext::CssContext () {
pos = 0;
- matchCache[CSS_PRIMARY_USER_AGENT].setSize (userAgentSheet.matchCacheOffset, -1);
+ matchCache.setSize (userAgentSheet.getRequiredMatchCache (), -1);
}
/**
@@ -505,28 +505,25 @@ void CssContext::apply (CssPropertyList *props, Doctree *docTree,
CssPropertyList *tagStyle, CssPropertyList *tagStyleImportant,
CssPropertyList *nonCssHints) {
- userAgentSheet.apply (props, docTree, node,
- &matchCache[CSS_PRIMARY_USER_AGENT]);
- sheet[CSS_PRIMARY_USER].apply (props, docTree, node,
- &matchCache[CSS_PRIMARY_USER]);
+ userAgentSheet.apply (props, docTree, node, &matchCache);
+
+ sheet[CSS_PRIMARY_USER].apply (props, docTree, node, &matchCache);
if (nonCssHints)
nonCssHints->apply (props);
- sheet[CSS_PRIMARY_AUTHOR].apply (props, docTree, node,
- &matchCache[CSS_PRIMARY_AUTHOR]);
+ sheet[CSS_PRIMARY_AUTHOR].apply (props, docTree, node, &matchCache);
if (tagStyle)
tagStyle->apply (props);
sheet[CSS_PRIMARY_AUTHOR_IMPORTANT].apply (props, docTree, node,
- &matchCache[CSS_PRIMARY_AUTHOR_IMPORTANT]);
+ &matchCache);
if (tagStyleImportant)
tagStyleImportant->apply (props);
- sheet[CSS_PRIMARY_USER_IMPORTANT].apply (props, docTree, node,
- &matchCache[CSS_PRIMARY_USER_IMPORTANT]);
+ sheet[CSS_PRIMARY_USER_IMPORTANT].apply (props, docTree, node, &matchCache);
}
void CssContext::addRule (CssSelector *sel, CssPropertyList *props,
@@ -540,12 +537,16 @@ void CssContext::addRule (CssSelector *sel, CssPropertyList *props,
!rule->isSafe ()) {
MSG_WARN ("Ignoring unsafe author style that might reveal browsing history\n");
delete rule;
- } else if (order == CSS_PRIMARY_USER_AGENT) {
- userAgentSheet.addRule (rule);
- matchCache[CSS_PRIMARY_USER_AGENT].setSize (userAgentSheet.matchCacheOffset, -1);
- } else {
- sheet[order].addRule (rule);
- matchCache[order].setSize (sheet[order].matchCacheOffset, -1);
+ } else {
+ rule->selector->setMatchCacheOffset(matchCache.size ());
+ if (rule->selector->getRequiredMatchCache () > matchCache.size ())
+ matchCache.setSize (rule->selector->getRequiredMatchCache (), -1);
+
+ if (order == CSS_PRIMARY_USER_AGENT) {
+ userAgentSheet.addRule (rule);
+ } else {
+ sheet[order].addRule (rule);
+ }
}
}
}