- Revision
- 132621
- Author
- [email protected]
- Date
- 2012-10-26 04:42:54 -0700 (Fri, 26 Oct 2012)
Log Message
[Shadow]: removing styles in shadow dom subtree causes crash.
https://bugs.webkit.org/show_bug.cgi?id=100455
Reviewed by Hajime Morita.
Source/WebCore:
To quickly check whether shadow roots or elements have any scoped
styles or not, elements have hasStyleScoped flag. If elements have
any scoped styles, the styles are direct children of the element.
The original code just sees how many chilren are scoped style or not.
However styles in shadow dom subtree are registered with the shadow
root but are not always direct children of shadow roots. So to check
whether shadow roots have any scoped styles, modified to count
number of styles registered with the shadow root.
Test: fast/dom/shadow/remove-styles-in-shadow-crash.html
* dom/Node.cpp:
(WebCore::Node::registerScopedHTMLStyleChild):
(WebCore::Node::unregisterScopedHTMLStyleChild):
Made the above two method virtual. class ShadowRoot overrides these
methods.
(WebCore::Node::numberOfScopedHTMLStyleChildren):
Moved HTMLStyleElement.cpp to Node.cpp, because the above two methods
are moved into Node.cpp.
* dom/Node.h:
(Node):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::registerScopedHTMLStyleChild):
(WebCore::ShadowRoot::unregisterScopedHTMLStyleChild):
Modify to count how many styles are registered with the shadow root.
The "counting" is done when styles are registered and unregistered
with the shadow root, i.e. style element is inserted into document or
removed from document. When unregister some style, there are no more
styles registered with the shadow root. Set style scoped flag false.
* dom/ShadowRoot.h:
(ShadowRoot):
* html/HTMLStyleElement.cpp:
* html/HTMLStyleElement.h:
(WebCore::HTMLStyleElement::isRegisteredAsScoped):
Now isRegisteredAsScoped is used in Node.cpp, so removed inline and
moved .cpp to .h.
LayoutTests:
* fast/dom/shadow/remove-styles-in-shadow-crash-expected.txt: Added.
* fast/dom/shadow/remove-styles-in-shadow-crash.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (132620 => 132621)
--- trunk/LayoutTests/ChangeLog 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/LayoutTests/ChangeLog 2012-10-26 11:42:54 UTC (rev 132621)
@@ -1,3 +1,13 @@
+2012-10-26 Takashi Sakamoto <[email protected]>
+
+ [Shadow]: removing styles in shadow dom subtree causes crash.
+ https://bugs.webkit.org/show_bug.cgi?id=100455
+
+ Reviewed by Hajime Morita.
+
+ * fast/dom/shadow/remove-styles-in-shadow-crash-expected.txt: Added.
+ * fast/dom/shadow/remove-styles-in-shadow-crash.html: Added.
+
2012-10-26 Sudarsana Nagineni <[email protected]>
[EFL] Gardening to make the bots green
Added: trunk/LayoutTests/fast/dom/shadow/remove-styles-in-shadow-crash-expected.txt (0 => 132621)
--- trunk/LayoutTests/fast/dom/shadow/remove-styles-in-shadow-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/remove-styles-in-shadow-crash-expected.txt 2012-10-26 11:42:54 UTC (rev 132621)
@@ -0,0 +1 @@
+PASS
Added: trunk/LayoutTests/fast/dom/shadow/remove-styles-in-shadow-crash.html (0 => 132621)
--- trunk/LayoutTests/fast/dom/shadow/remove-styles-in-shadow-crash.html (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/remove-styles-in-shadow-crash.html 2012-10-26 11:42:54 UTC (rev 132621)
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+<head>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+function runTest() {
+ var host = document.getElementById('host');
+ var sr = new WebKitShadowRoot(host);
+ // Test the case: two styles are in shadow dom subtree and they are not
+ // direct chilren of the shadow root.
+ sr.innerHTML = '<div><style>div { color: blue; }</style>Hello</div><div><style>span { color: red }</style><span>World</span></div>';
+ sr.innerHTML = '';
+
+ // Test the case: two styles are in shadow dom subtree, but one is a direct
+ // child of shadow root and scoped. The other is not a direct child and
+ // not scoped.
+ sr.innerHTML = '<style scoped>div { color: blue; }</style>Hello<div><style>span { color: red }</style><span>World</span></div>';
+ sr.innerHTML = '';
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <!-- [Bug 100455], https://bugs.webkit.org/show_bug.cgi?id=100455 -->
+ <!-- [Shadow]: removing styles in shadow dom subtree causes crash. -->
+ <!-- If this test passes, we can see just "PASS" without any crashes. -->
+ <div id="host"></div>
+ <div>PASS</div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (132620 => 132621)
--- trunk/Source/WebCore/ChangeLog 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/ChangeLog 2012-10-26 11:42:54 UTC (rev 132621)
@@ -1,3 +1,48 @@
+2012-10-26 Takashi Sakamoto <[email protected]>
+
+ [Shadow]: removing styles in shadow dom subtree causes crash.
+ https://bugs.webkit.org/show_bug.cgi?id=100455
+
+ Reviewed by Hajime Morita.
+
+ To quickly check whether shadow roots or elements have any scoped
+ styles or not, elements have hasStyleScoped flag. If elements have
+ any scoped styles, the styles are direct children of the element.
+ The original code just sees how many chilren are scoped style or not.
+ However styles in shadow dom subtree are registered with the shadow
+ root but are not always direct children of shadow roots. So to check
+ whether shadow roots have any scoped styles, modified to count
+ number of styles registered with the shadow root.
+
+ Test: fast/dom/shadow/remove-styles-in-shadow-crash.html
+
+ * dom/Node.cpp:
+ (WebCore::Node::registerScopedHTMLStyleChild):
+ (WebCore::Node::unregisterScopedHTMLStyleChild):
+ Made the above two method virtual. class ShadowRoot overrides these
+ methods.
+ (WebCore::Node::numberOfScopedHTMLStyleChildren):
+ Moved HTMLStyleElement.cpp to Node.cpp, because the above two methods
+ are moved into Node.cpp.
+ * dom/Node.h:
+ (Node):
+ * dom/ShadowRoot.cpp:
+ (WebCore::ShadowRoot::ShadowRoot):
+ (WebCore::ShadowRoot::registerScopedHTMLStyleChild):
+ (WebCore::ShadowRoot::unregisterScopedHTMLStyleChild):
+ Modify to count how many styles are registered with the shadow root.
+ The "counting" is done when styles are registered and unregistered
+ with the shadow root, i.e. style element is inserted into document or
+ removed from document. When unregister some style, there are no more
+ styles registered with the shadow root. Set style scoped flag false.
+ * dom/ShadowRoot.h:
+ (ShadowRoot):
+ * html/HTMLStyleElement.cpp:
+ * html/HTMLStyleElement.h:
+ (WebCore::HTMLStyleElement::isRegisteredAsScoped):
+ Now isRegisteredAsScoped is used in Node.cpp, so removed inline and
+ moved .cpp to .h.
+
2012-10-26 Sheriff Bot <[email protected]>
Unreviewed, rolling out r132589.
Modified: trunk/Source/WebCore/dom/Node.cpp (132620 => 132621)
--- trunk/Source/WebCore/dom/Node.cpp 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/dom/Node.cpp 2012-10-26 11:42:54 UTC (rev 132621)
@@ -64,6 +64,7 @@
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
+#include "HTMLStyleElement.h"
#include "InspectorCounters.h"
#include "KeyboardEvent.h"
#include "LabelsNodeList.h"
@@ -2844,6 +2845,28 @@
range->textRects(rects);
}
+void Node::registerScopedHTMLStyleChild()
+{
+ setHasScopedHTMLStyleChild(true);
+}
+
+void Node::unregisterScopedHTMLStyleChild()
+{
+ ASSERT(hasScopedHTMLStyleChild());
+ setHasScopedHTMLStyleChild(numberOfScopedHTMLStyleChildren());
+}
+
+size_t Node::numberOfScopedHTMLStyleChildren() const
+{
+ size_t count = 0;
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(HTMLNames::styleTag) && static_cast<HTMLStyleElement*>(child)->isRegisteredAsScoped())
+ count++;
+ }
+
+ return count;
+}
+
} // namespace WebCore
#ifndef NDEBUG
Modified: trunk/Source/WebCore/dom/Node.h (132620 => 132621)
--- trunk/Source/WebCore/dom/Node.h 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/dom/Node.h 2012-10-26 11:42:54 UTC (rev 132621)
@@ -662,8 +662,8 @@
void notifyMutationObserversNodeWillDetach();
#endif // ENABLE(MUTATION_OBSERVERS)
- void registerScopedHTMLStyleChild();
- void unregisterScopedHTMLStyleChild();
+ virtual void registerScopedHTMLStyleChild();
+ virtual void unregisterScopedHTMLStyleChild();
size_t numberOfScopedHTMLStyleChildren() const;
virtual void reportMemoryUsage(MemoryObjectInfo*) const;
Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (132620 => 132621)
--- trunk/Source/WebCore/dom/ShadowRoot.cpp 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp 2012-10-26 11:42:54 UTC (rev 132621)
@@ -57,6 +57,7 @@
, m_resetStyleInheritance(false)
, m_insertionPointAssignedTo(0)
, m_numberOfShadowElementChildren(0)
+ , m_numberOfStyles(0)
{
ASSERT(document);
@@ -246,4 +247,17 @@
owner()->invalidateDistribution();
}
+void ShadowRoot::registerScopedHTMLStyleChild()
+{
+ ++m_numberOfStyles;
+ setHasScopedHTMLStyleChild(true);
}
+
+void ShadowRoot::unregisterScopedHTMLStyleChild()
+{
+ ASSERT(hasScopedHTMLStyleChild() && m_numberOfStyles > 0);
+ --m_numberOfStyles;
+ setHasScopedHTMLStyleChild(m_numberOfStyles > 0);
+}
+
+}
Modified: trunk/Source/WebCore/dom/ShadowRoot.h (132620 => 132621)
--- trunk/Source/WebCore/dom/ShadowRoot.h 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/dom/ShadowRoot.h 2012-10-26 11:42:54 UTC (rev 132621)
@@ -93,6 +93,9 @@
void unregisterShadowElement() { --m_numberOfShadowElementChildren; }
bool hasShadowInsertionPoint() const { return m_numberOfShadowElementChildren > 0; }
+ virtual void registerScopedHTMLStyleChild() OVERRIDE;
+ virtual void unregisterScopedHTMLStyleChild() OVERRIDE;
+
#ifndef NDEBUG
ShadowRootType type() const { return m_type; }
#endif
@@ -113,6 +116,7 @@
bool m_resetStyleInheritance : 1;
InsertionPoint* m_insertionPointAssignedTo;
size_t m_numberOfShadowElementChildren;
+ size_t m_numberOfStyles;
#ifndef NDEBUG
ShadowRootType m_type;
Modified: trunk/Source/WebCore/html/HTMLStyleElement.cpp (132620 => 132621)
--- trunk/Source/WebCore/html/HTMLStyleElement.cpp 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/html/HTMLStyleElement.cpp 2012-10-26 11:42:54 UTC (rev 132621)
@@ -122,40 +122,6 @@
HTMLElement::finishParsingChildren();
}
-inline bool HTMLStyleElement::isRegisteredAsScoped() const
-{
- // Note: We cannot rely on the 'scoped' attribute still being present when this method is invoked.
- // Therefore we cannot rely on scoped()!
- if (m_scopedStyleRegistrationState == NotRegistered)
- return false;
- return true;
-}
-
-// These three Node methods are placed here to
-// make the header inclusion dependency sane.
-
-inline void Node::registerScopedHTMLStyleChild()
-{
- setHasScopedHTMLStyleChild(true);
-}
-
-inline void Node::unregisterScopedHTMLStyleChild()
-{
- ASSERT(hasScopedHTMLStyleChild());
- setHasScopedHTMLStyleChild(numberOfScopedHTMLStyleChildren());
-}
-
-size_t Node::numberOfScopedHTMLStyleChildren() const
-{
- size_t count = 0;
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(styleTag) && static_cast<HTMLStyleElement*>(child)->isRegisteredAsScoped())
- count++;
- }
-
- return count;
-}
-
void HTMLStyleElement::registerWithScopingNode(bool scoped)
{
// Note: We cannot rely on the 'scoped' element already being present when this method is invoked.
Modified: trunk/Source/WebCore/html/HTMLStyleElement.h (132620 => 132621)
--- trunk/Source/WebCore/html/HTMLStyleElement.h 2012-10-26 11:40:16 UTC (rev 132620)
+++ trunk/Source/WebCore/html/HTMLStyleElement.h 2012-10-26 11:42:54 UTC (rev 132621)
@@ -44,7 +44,14 @@
bool scoped() const;
void setScoped(bool);
Element* scopingElement() const;
- bool isRegisteredAsScoped() const;
+ bool isRegisteredAsScoped() const
+ {
+ // Note: We cannot rely on the 'scoped' attribute still being present when this method is invoked.
+ // Therefore we cannot rely on scoped()!
+ if (m_scopedStyleRegistrationState == NotRegistered)
+ return false;
+ return true;
+ }
using StyleElement::sheet;