Commit 669ec61c authored by morrita@chromium.org's avatar morrita@chromium.org

Don't call ill-balanced removeStyleSheetCandidateNode()

There are possibilities where removeStyleSheetCandidateNode()
is called without addStyleSheetCandidateNode(). We should prevent this
because StyleEngine assumes that its call is balanced.

This change add a flag to ensure it being balanced.

BUG=353525
R=ojan@chromium.org, eseidel@chromium.org
TEST=style-onload-remove-crash.html

Review URL: https://codereview.chromium.org/203253006

git-svn-id: svn://svn.chromium.org/blink/trunk@169691 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3aedc061
<!DOCTYPE html>
<body>
<script src="../../../resources/js-test.js"></script>
<div></div>
<script>
myDiv = document.body.querySelector("div");
newStyle = document.createElement("style");
newStyle.onload = function() { document.body.appendChild(myDiv); }
document.body.appendChild(newStyle);
newDiv = document.createElement("div");
// Inserting <iframe> into tree flushes the pending @onload event.
newDiv.innerHTML = "<iframe></iframe><style></style>";
myDiv.createShadowRoot().appendChild(newDiv);
debug("PASS unless crash");
</script>
</body>
......@@ -43,6 +43,7 @@ static bool isCSS(Element* element, const AtomicString& type)
StyleElement::StyleElement(Document* document, bool createdByParser)
: m_createdByParser(createdByParser)
, m_loading(false)
, m_registeredAsCandidate(false)
, m_startPosition(TextPosition::belowRangePosition())
{
if (createdByParser && document && document->scriptableDocumentParser() && !document->isInDocumentWrite())
......@@ -59,6 +60,8 @@ void StyleElement::processStyleSheet(Document& document, Element* element)
{
TRACE_EVENT0("webkit", "StyleElement::processStyleSheet");
ASSERT(element);
m_registeredAsCandidate = true;
document.styleEngine()->addStyleSheetCandidateNode(element, m_createdByParser);
if (m_createdByParser)
return;
......@@ -74,7 +77,14 @@ void StyleElement::removedFromDocument(Document& document, Element* element)
void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode, TreeScope& treeScope)
{
ASSERT(element);
if (!m_registeredAsCandidate) {
ASSERT(!m_sheet);
return;
}
document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
m_registeredAsCandidate = false;
RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
......
......@@ -60,8 +60,9 @@ private:
void process(Element*);
void clearSheet(Element* ownerElement = 0);
bool m_createdByParser;
bool m_loading;
bool m_createdByParser : 1;
bool m_loading : 1;
bool m_registeredAsCandidate : 1;
TextPosition m_startPosition;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment