Diff
Modified: trunk/LayoutTests/ChangeLog (196997 => 196998)
--- trunk/LayoutTests/ChangeLog 2016-02-23 22:29:01 UTC (rev 196997)
+++ trunk/LayoutTests/ChangeLog 2016-02-23 22:35:44 UTC (rev 196998)
@@ -1,3 +1,21 @@
+2016-02-22 Ryosuke Niwa <[email protected]>
+
+ Calling importNode on shadow root causes a crash
+ https://bugs.webkit.org/show_bug.cgi?id=154570
+
+ Reviewed by Anders Carlsson.
+
+ Added W3C-style testharness tests for calling cloneNode on a shadow root.
+
+ Also added tests for adoptNode and importNode.
+
+ * fast/shadow-dom/Document-prototype-adoptNode-expected.txt: Added.
+ * fast/shadow-dom/Document-prototype-adoptNode.html: Added.
+ * fast/shadow-dom/Document-prototype-importNode-expected.txt: Added.
+ * fast/shadow-dom/Document-prototype-importNode.html: Added.
+ * fast/shadow-dom/Node-prototype-cloneNode-expected.txt: Added.
+ * fast/shadow-dom/Node-prototype-cloneNode.html: Added.
+
2016-02-23 Daniel Bates <[email protected]>
REGRESSION (r196892): No longer emit error message when CSP form-action directive is used as a source _expression_
Added: trunk/LayoutTests/fast/shadow-dom/Document-prototype-adoptNode-expected.txt (0 => 196998)
--- trunk/LayoutTests/fast/shadow-dom/Document-prototype-adoptNode-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Document-prototype-adoptNode-expected.txt 2016-02-23 22:35:44 UTC (rev 196998)
@@ -0,0 +1,4 @@
+
+PASS adoptNode on a shadow root in open mode must throw a HierarchyRequestError
+PASS adoptNode on a shadow root in closed mode must throw a HierarchyRequestError
+
Added: trunk/LayoutTests/fast/shadow-dom/Document-prototype-adoptNode.html (0 => 196998)
--- trunk/LayoutTests/fast/shadow-dom/Document-prototype-adoptNode.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Document-prototype-adoptNode.html 2016-02-23 22:35:44 UTC (rev 196998)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>DOM and Shadow DOM: Document.prototype.adoptNode</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="The adoptNode(node) method must throw a HierarchyRequestError exception if node is a shadow root.">
+<link rel="help" href=""
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testAdoptNode(mode) {
+ test(function () {
+ var newDocument = document.implementation.createHTMLDocument();
+ assert_throws({'name': 'HierarchyRequestError'}, function () {
+ var element = document.createElement('div');
+ var shadowRoot = element.attachShadow({mode: mode});
+ newDocument.adoptNode(shadowRoot);
+ });
+ }, 'adoptNode on a shadow root in ' + mode + ' mode must throw a HierarchyRequestError');
+}
+
+testAdoptNode('open');
+testAdoptNode('closed');
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/Document-prototype-importNode-expected.txt (0 => 196998)
--- trunk/LayoutTests/fast/shadow-dom/Document-prototype-importNode-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Document-prototype-importNode-expected.txt 2016-02-23 22:35:44 UTC (rev 196998)
@@ -0,0 +1,4 @@
+
+PASS importNode on a shadow root in open mode must throw a NotSupportedError
+PASS importNode on a shadow root in closed mode must throw a NotSupportedError
+
Added: trunk/LayoutTests/fast/shadow-dom/Document-prototype-importNode.html (0 => 196998)
--- trunk/LayoutTests/fast/shadow-dom/Document-prototype-importNode.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Document-prototype-importNode.html 2016-02-23 22:35:44 UTC (rev 196998)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>DOM and Shadow DOM: Document.prototype.importNode</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="The importNode(node, deep) method must throw a NotSupportedError exception if node is a shadow root.">
+<link rel="help" href=""
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testImportNode(mode) {
+ test(function () {
+ var newDocument = document.implementation.createHTMLDocument();
+ assert_throws({'name': 'NotSupportedError'}, function () {
+ var element = document.createElement('div');
+ var shadowRoot = element.attachShadow({mode: mode});
+ newDocument.importNode(shadowRoot);
+ });
+ }, 'importNode on a shadow root in ' + mode + ' mode must throw a NotSupportedError');
+}
+
+testImportNode('open');
+testImportNode('closed');
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/Node-prototype-cloneNode-expected.txt (0 => 196998)
--- trunk/LayoutTests/fast/shadow-dom/Node-prototype-cloneNode-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Node-prototype-cloneNode-expected.txt 2016-02-23 22:35:44 UTC (rev 196998)
@@ -0,0 +1,5 @@
+
+PASS cloneNode on a shadow root in open mode must throw a NotSupportedError
+PASS cloneNode on a shadow root in closed mode must throw a NotSupportedError
+PASS cloneNode on an open shadow root must throw a NotSupportedError
+
Added: trunk/LayoutTests/fast/shadow-dom/Node-prototype-cloneNode.html (0 => 196998)
--- trunk/LayoutTests/fast/shadow-dom/Node-prototype-cloneNode.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Node-prototype-cloneNode.html 2016-02-23 22:35:44 UTC (rev 196998)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Shadow DOM: Extensions to Node interface</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="Invoking the cloneNode() method on a ShadowRoot instance must always throw a NotSupportedError.">
+<link rel="help" href=""
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testCloneNode(mode) {
+ test(function () {
+ assert_throws({'name': 'NotSupportedError'}, function () {
+ var element = document.createElement('div');
+ var shadowRoot = element.attachShadow({mode: mode});
+ shadowRoot.cloneNode(false);
+ }, 'cloneNode(false) on a shadow root in ' + mode + ' mode must throw a NotSupportedError');
+
+ assert_throws({'name': 'NotSupportedError'}, function () {
+ var element = document.createElement('div');
+ var shadowRoot = element.attachShadow({mode: mode});
+ shadowRoot.cloneNode(false);
+ }, 'cloneNode(true) on a closed shadow root must throw a NotSupportedError');
+
+ }, 'cloneNode on a shadow root in ' + mode + ' mode must throw a NotSupportedError');
+}
+
+testCloneNode('open');
+testCloneNode('closed');
+
+test(function () {
+ var element = document.createElement('div');
+ var shadowRoot = element.attachShadow({mode: 'open'});
+
+ assert_equals(element.cloneNode(false).shadowRoot, null, 'cloneNode(false) on an open shadow host mode must clone its shadow root');
+ assert_equals(element.cloneNode(true).shadowRoot, null, 'cloneNode(true) on an open shadow host mode must clone its shadow root');
+}, 'cloneNode on an open shadow root must throw a NotSupportedError');
+
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (196997 => 196998)
--- trunk/Source/WebCore/ChangeLog 2016-02-23 22:29:01 UTC (rev 196997)
+++ trunk/Source/WebCore/ChangeLog 2016-02-23 22:35:44 UTC (rev 196998)
@@ -1,3 +1,34 @@
+2016-02-22 Ryosuke Niwa <[email protected]>
+
+ Calling importNode on shadow root causes a crash
+ https://bugs.webkit.org/show_bug.cgi?id=154570
+
+ Reviewed by Anders Carlsson.
+
+ The bug was caused by a missing check in cloneNode. Added cloneNodeForBindings to explicitly throw
+ an NotSupportedError when it's called on a shadow root. We don't clone shadow root when deep-cloning
+ the tree so we don't have to check that condition.
+
+ The behavior of cloneNode is specified at:
+ http://w3c.github.io/webcomponents/spec/shadow/#the-shadowroot-interface
+ (it current says we should throw DATA_CLONE_ERR but I have an spec bug filed at
+ https://github.com/w3c/webcomponents/issues/393)
+
+ The behavior of importNode and adoptNode are specified in DOM4 specification:
+ https://dom.spec.whatwg.org/#dom-document-importnode
+ https://dom.spec.whatwg.org/#dom-document-adoptnode
+
+ Tests: fast/shadow-dom/Document-prototype-adoptNode.html
+ fast/shadow-dom/Document-prototype-importNode.html
+ fast/shadow-dom/Node-prototype-cloneNode.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::importNode): Throw NotSupportedError when importing a shadow root.
+ * dom/Node.cpp:
+ (WebCore::Node::cloneNodeForBindings): Added.
+ * dom/Node.h:
+ * dom/Node.idl: Use cloneNodeForBindings here.
+
2016-02-23 Daniel Bates <[email protected]>
REGRESSION (r196892): No longer emit error message when CSP form-action directive is used as a source _expression_
Modified: trunk/Source/WebCore/dom/Document.cpp (196997 => 196998)
--- trunk/Source/WebCore/dom/Document.cpp 2016-02-23 22:29:01 UTC (rev 196997)
+++ trunk/Source/WebCore/dom/Document.cpp 2016-02-23 22:35:44 UTC (rev 196998)
@@ -985,12 +985,15 @@
}
switch (importedNode->nodeType()) {
+ case DOCUMENT_FRAGMENT_NODE:
+ if (importedNode->isShadowRoot())
+ break;
+ FALLTHROUGH;
case ELEMENT_NODE:
case TEXT_NODE:
case CDATA_SECTION_NODE:
case PROCESSING_INSTRUCTION_NODE:
case COMMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
return importedNode->cloneNodeInternal(document(), deep ? CloningOperation::Everything : CloningOperation::OnlySelf);
case ATTRIBUTE_NODE:
Modified: trunk/Source/WebCore/dom/Node.cpp (196997 => 196998)
--- trunk/Source/WebCore/dom/Node.cpp 2016-02-23 22:29:01 UTC (rev 196997)
+++ trunk/Source/WebCore/dom/Node.cpp 2016-02-23 22:35:44 UTC (rev 196998)
@@ -602,6 +602,15 @@
}
}
+RefPtr<Node> Node::cloneNodeForBindings(bool deep, ExceptionCode& ec)
+{
+ if (UNLIKELY(isShadowRoot())) {
+ ec = NOT_SUPPORTED_ERR;
+ return nullptr;
+ }
+ return cloneNode(deep);
+}
+
const AtomicString& Node::prefix() const
{
// For nodes other than elements and attributes, the prefix is always null
Modified: trunk/Source/WebCore/dom/Node.h (196997 => 196998)
--- trunk/Source/WebCore/dom/Node.h 2016-02-23 22:29:01 UTC (rev 196997)
+++ trunk/Source/WebCore/dom/Node.h 2016-02-23 22:35:44 UTC (rev 196998)
@@ -181,6 +181,7 @@
};
virtual Ref<Node> cloneNodeInternal(Document&, CloningOperation) = 0;
Ref<Node> cloneNode(bool deep) { return cloneNodeInternal(document(), deep ? CloningOperation::Everything : CloningOperation::OnlySelf); }
+ RefPtr<Node> cloneNodeForBindings(bool deep, ExceptionCode&);
virtual const AtomicString& localName() const;
virtual const AtomicString& namespaceURI() const;
Modified: trunk/Source/WebCore/dom/Node.idl (196997 => 196998)
--- trunk/Source/WebCore/dom/Node.idl 2016-02-23 22:29:01 UTC (rev 196997)
+++ trunk/Source/WebCore/dom/Node.idl 2016-02-23 22:35:44 UTC (rev 196998)
@@ -70,7 +70,7 @@
[Custom, RaisesException] Node appendChild([CustomReturn] Node newChild);
boolean hasChildNodes();
- [NewObject] Node cloneNode([Default=Undefined] optional boolean deep);
+ [NewObject, RaisesException, ImplementedAs=cloneNodeForBindings] Node cloneNode([Default=Undefined] optional boolean deep);
void normalize();
// Introduced in DOM Level 2: