- Revision
- 259152
- Author
- [email protected]
- Date
- 2020-03-27 21:00:36 -0700 (Fri, 27 Mar 2020)
Log Message
Source/WebCore:
Fix null pointer crash in RenderBox::styleDidChange
https://bugs.webkit.org/show_bug.cgi?id=208311
Patch by Eugene But <[email protected]> on 2020-03-27
Reviewed by Ryosuke Niwa.
RenderBox::styleDidChange crashes when changing style for HTMLBodyElement element.
Crash happens on dereferencing null document().documentElement()->renderer() pointer:
if (.... || !documentElementRenderer->style().hasExplicitlySetWritingMode())) {
That HTMLBodyElement was added as the second child of document, which is not allowed per spec:
If parent is a document, and any of the statements below, switched on node,
are true, then throw a "HierarchyRequestError" DOMException:
.......
element
parent has an element child that is not child or a doctype is following child.
......
https://dom.spec.whatwg.org/#concept-node-replace
This patch prevents adding HTMLBodyElement as the second child by running more strict checks
inside WebCore::Document::canAcceptChild(). Previously canAcceptChild() would allow all
Replace operations if new child had the same type as old child, even if old child has changed the parent.
If old child has changed the parent (parent is not document), it means that child was removed from document
and it is possible that mutation event handler has already added a new child to document. This is normal
situation, but it means that canAcceptChild() can not short circuit only on comparing the types of old and
new child, and has to run all checks listed in https://dom.spec.whatwg.org/#concept-node-replace
Tests: fast/dom/add-document-child-during-document-child-replacement.html
fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement.html
* Source/WebCore/dom/Document.cpp:
(WebCore::Document::canAcceptChild):
LayoutTests:
Test for RenderBox::styleDidChange crash fix
https://bugs.webkit.org/show_bug.cgi?id=208311
Patch by Eugene But <[email protected]> on 2020-03-27
Reviewed by Ryosuke Niwa
add-document-child-during-document-child-replacement.html test adds svg child to a document
from mutation event observer while existing document child is being replaced.
After adding svg child, the document should reject the replacement of existing child, per spec:
If parent is a document, and any of the statements below, switched on node,
are true, then throw a "HierarchyRequestError" DOMException:
.......
element
parent has an element child that is not child or a doctype is following child.
......
https://dom.spec.whatwg.org/#concept-node-replace
add-document-child-and-reparent-old-child-during-document-child-replacement.html reparents the old child
to create slightly different state where old child still has a parent but that parent is not document.
* add-document-child-during-document-child-replacement.html:
* add-document-child-and-reparent-old-child-during-document-child-replacement.html:
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (259151 => 259152)
--- trunk/LayoutTests/ChangeLog 2020-03-28 03:05:01 UTC (rev 259151)
+++ trunk/LayoutTests/ChangeLog 2020-03-28 04:00:36 UTC (rev 259152)
@@ -1,3 +1,28 @@
+2020-03-27 Eugene But <[email protected]>
+
+ Test for RenderBox::styleDidChange crash fix
+ https://bugs.webkit.org/show_bug.cgi?id=208311
+
+ Reviewed by Ryosuke Niwa
+
+ add-document-child-during-document-child-replacement.html test adds svg child to a document
+ from mutation event observer while existing document child is being replaced.
+ After adding svg child, the document should reject the replacement of existing child, per spec:
+
+ If parent is a document, and any of the statements below, switched on node,
+ are true, then throw a "HierarchyRequestError" DOMException:
+ .......
+ element
+ parent has an element child that is not child or a doctype is following child.
+ ......
+ https://dom.spec.whatwg.org/#concept-node-replace
+
+ add-document-child-and-reparent-old-child-during-document-child-replacement.html reparents the old child
+ to create slightly different state where old child still has a parent but that parent is not document.
+
+ * add-document-child-during-document-child-replacement.html:
+ * add-document-child-and-reparent-old-child-during-document-child-replacement.html:
+
2020-03-27 Jason Lawrence <[email protected]>
[ Mac wk2 ] MediaPlayerPrivateInterface crash in WebKit::VideoFullscreenManager
Added: trunk/LayoutTests/fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement-expected.txt (0 => 259152)
--- trunk/LayoutTests/fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement-expected.txt 2020-03-28 04:00:36 UTC (rev 259152)
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: line 9: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 9: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 9: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 9: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 9: HierarchyRequestError: The operation would yield an incorrect node tree.
+PASS document.replaceChild(document.body, document.documentElement) threw exception HierarchyRequestError: The operation would yield an incorrect node tree..
+
Added: trunk/LayoutTests/fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement.html (0 => 259152)
--- trunk/LayoutTests/fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement.html (rev 0)
+++ trunk/LayoutTests/fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement.html 2020-03-28 04:00:36 UTC (rev 259152)
@@ -0,0 +1,14 @@
+<body dir="rtl"></body>
+<script src=""
+<script>
+ let documentDocumentElement = document.documentElement;
+ document.body.offsetHeight;
+ document.addEventListener("DOMSubtreeModified", function() {
+ document.execCommand("SelectAll");
+ let svg = document.createElementNS("http://www.w3.org/2000/svg", "desc");
+ document.appendChild(svg);
+ document.createElement('div').appendChild(documentDocumentElement);
+ });
+
+ shouldThrowErrorName("document.replaceChild(document.body, document.documentElement)", "HierarchyRequestError");
+</script>
Added: trunk/LayoutTests/fast/dom/add-document-child-during-document-child-replacement-expected.txt (0 => 259152)
--- trunk/LayoutTests/fast/dom/add-document-child-during-document-child-replacement-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/add-document-child-during-document-child-replacement-expected.txt 2020-03-28 04:00:36 UTC (rev 259152)
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: line 8: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 8: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 8: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 8: HierarchyRequestError: The operation would yield an incorrect node tree.
+CONSOLE MESSAGE: line 8: HierarchyRequestError: The operation would yield an incorrect node tree.
+PASS document.replaceChild(document.body, document.documentElement) threw exception HierarchyRequestError: The operation would yield an incorrect node tree..
+
Added: trunk/LayoutTests/fast/dom/add-document-child-during-document-child-replacement.html (0 => 259152)
--- trunk/LayoutTests/fast/dom/add-document-child-during-document-child-replacement.html (rev 0)
+++ trunk/LayoutTests/fast/dom/add-document-child-during-document-child-replacement.html 2020-03-28 04:00:36 UTC (rev 259152)
@@ -0,0 +1,12 @@
+<body dir="rtl"></body>
+<script src=""
+<script>
+ document.body.offsetHeight;
+ document.addEventListener("DOMSubtreeModified", function() {
+ document.execCommand("SelectAll");
+ let svg = document.createElementNS("http://www.w3.org/2000/svg", "desc");
+ document.appendChild(svg);
+ });
+
+ shouldThrowErrorName("document.replaceChild(document.body, document.documentElement)", "HierarchyRequestError");
+</script>
Modified: trunk/Source/WebCore/ChangeLog (259151 => 259152)
--- trunk/Source/WebCore/ChangeLog 2020-03-28 03:05:01 UTC (rev 259151)
+++ trunk/Source/WebCore/ChangeLog 2020-03-28 04:00:36 UTC (rev 259152)
@@ -1,3 +1,40 @@
+2020-03-27 Eugene But <[email protected]>
+
+ Fix null pointer crash in RenderBox::styleDidChange
+ https://bugs.webkit.org/show_bug.cgi?id=208311
+
+ Reviewed by Ryosuke Niwa.
+
+ RenderBox::styleDidChange crashes when changing style for HTMLBodyElement element.
+ Crash happens on dereferencing null document().documentElement()->renderer() pointer:
+
+ if (.... || !documentElementRenderer->style().hasExplicitlySetWritingMode())) {
+
+ That HTMLBodyElement was added as the second child of document, which is not allowed per spec:
+
+ If parent is a document, and any of the statements below, switched on node,
+ are true, then throw a "HierarchyRequestError" DOMException:
+ .......
+ element
+ parent has an element child that is not child or a doctype is following child.
+ ......
+ https://dom.spec.whatwg.org/#concept-node-replace
+
+ This patch prevents adding HTMLBodyElement as the second child by running more strict checks
+ inside WebCore::Document::canAcceptChild(). Previously canAcceptChild() would allow all
+ Replace operations if new child had the same type as old child, even if old child has changed the parent.
+
+ If old child has changed the parent (parent is not document), it means that child was removed from document
+ and it is possible that mutation event handler has already added a new child to document. This is normal
+ situation, but it means that canAcceptChild() can not short circuit only on comparing the types of old and
+ new child, and has to run all checks listed in https://dom.spec.whatwg.org/#concept-node-replace
+
+ Tests: fast/dom/add-document-child-during-document-child-replacement.html
+ fast/dom/add-document-child-and-reparent-old-child-during-document-child-replacement.html
+
+ * Source/WebCore/dom/Document.cpp:
+ (WebCore::Document::canAcceptChild):
+
2020-03-27 Wenson Hsieh <[email protected]>
Web content processes should not be able to arbitrarily request pasteboard data from the UI process
Modified: trunk/Source/WebCore/dom/Document.cpp (259151 => 259152)
--- trunk/Source/WebCore/dom/Document.cpp 2020-03-28 03:05:01 UTC (rev 259151)
+++ trunk/Source/WebCore/dom/Document.cpp 2020-03-28 04:00:36 UTC (rev 259152)
@@ -3879,7 +3879,7 @@
bool Document::canAcceptChild(const Node& newChild, const Node* refChild, AcceptChildOperation operation) const
{
- if (operation == AcceptChildOperation::Replace && refChild->nodeType() == newChild.nodeType())
+ if (operation == AcceptChildOperation::Replace && refChild->parentNode() == this && refChild->nodeType() == newChild.nodeType())
return true;
switch (newChild.nodeType()) {