[Shadow DOM][V8] Assertion failure when shadow host is reclaimed before ShadowRoot
https://bugs.webkit.org/show_bug.cgi?id=102893
Reviewed by Kentaro Hara.
Source/WebCore:
Due to bug 88834, shadow hosts can be reclaimed before
corresponding ShadowRoots are. This breaks an invariant, that is,
the host is always available for any ShadowRoot. This change adds
guards for the possibly broken invariant.
Since bug 88834 is planned to be fixed shortly, this change
doesn't aim to fix this problem by make it work correctly, but
just lays a safety net which is needed until the root cause is
gone.
Test: fast/dom/shadow/host-wrapper-reclaimed.html
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::setInnerHTML):
(WebCore::ShadowRoot::setApplyAuthorStyles):
(WebCore::ShadowRoot::setResetStyleInheritance):
(WebCore::ShadowRoot::childrenChanged):
LayoutTests:
* fast/dom/shadow/host-wrapper-reclaimed-expected.txt: Added.
* fast/dom/shadow/host-wrapper-reclaimed.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@135456 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f13052f..ddf5787 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2012-11-21 Hajime Morrita <morrita@google.com>
+
+ [Shadow DOM][V8] Assertion failure when shadow host is reclaimed before ShadowRoot
+ https://bugs.webkit.org/show_bug.cgi?id=102893
+
+ Reviewed by Kentaro Hara.
+
+ * fast/dom/shadow/host-wrapper-reclaimed-expected.txt: Added.
+ * fast/dom/shadow/host-wrapper-reclaimed.html: Added.
+
2012-11-21 Daniel Bates <dbates@webkit.org>
JavaScript fails to concatenate large strings
diff --git a/LayoutTests/fast/dom/shadow/host-wrapper-reclaimed-expected.txt b/LayoutTests/fast/dom/shadow/host-wrapper-reclaimed-expected.txt
new file mode 100644
index 0000000..46cc850
--- /dev/null
+++ b/LayoutTests/fast/dom/shadow/host-wrapper-reclaimed-expected.txt
@@ -0,0 +1 @@
+PASS unless crash.
diff --git a/LayoutTests/fast/dom/shadow/host-wrapper-reclaimed.html b/LayoutTests/fast/dom/shadow/host-wrapper-reclaimed.html
new file mode 100644
index 0000000..19a0a96
--- /dev/null
+++ b/LayoutTests/fast/dom/shadow/host-wrapper-reclaimed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+function makeOrphanShadow() {
+ var host = document.createElement("div");
+ var shadow = new WebKitShadowRoot(host);
+ return shadow;
+};
+
+var shadow = makeOrphanShadow();
+gc(true);
+
+try { shadow.innerHTML = "Hello"; } catch(e) { }
+shadow.appendChild(document.createElement("span"));
+shadow.resetStyleInheritance = true;
+shadow.applyAuthorStyles = false;
+
+document.body.innerHTML = "PASS unless crash.";
+</script>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 2cb9e47..0c36646 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2012-11-21 Hajime Morrita <morrita@google.com>
+
+ [Shadow DOM][V8] Assertion failure when shadow host is reclaimed before ShadowRoot
+ https://bugs.webkit.org/show_bug.cgi?id=102893
+
+ Reviewed by Kentaro Hara.
+
+ Due to bug 88834, shadow hosts can be reclaimed before
+ corresponding ShadowRoots are. This breaks an invariant, that is,
+ the host is always available for any ShadowRoot. This change adds
+ guards for the possibly broken invariant.
+
+ Since bug 88834 is planned to be fixed shortly, this change
+ doesn't aim to fix this problem by make it work correctly, but
+ just lays a safety net which is needed until the root cause is
+ gone.
+
+ Test: fast/dom/shadow/host-wrapper-reclaimed.html
+
+ * dom/ShadowRoot.cpp:
+ (WebCore::ShadowRoot::setInnerHTML):
+ (WebCore::ShadowRoot::setApplyAuthorStyles):
+ (WebCore::ShadowRoot::setResetStyleInheritance):
+ (WebCore::ShadowRoot::childrenChanged):
+
2012-11-21 Dirk Schulze <krit@webkit.org>
Make CachedSVGDocumentReference independent of FilterOperation
diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp
index c62396a..f3c0646 100644
--- a/Source/WebCore/dom/ShadowRoot.cpp
+++ b/Source/WebCore/dom/ShadowRoot.cpp
@@ -46,6 +46,13 @@
#include "StyleResolver.h"
#include "markup.h"
+// FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
+#define GuardOrphanShadowRoot(rejectStatement) \
+ if (!this->host()) { \
+ rejectStatement; \
+ return; \
+ }
+
namespace WebCore {
ShadowRoot::ShadowRoot(Document* document)
@@ -171,6 +178,8 @@
void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
{
+ GuardOrphanShadowRoot(ec = INVALID_ACCESS_ERR);
+
if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, ec))
replaceChildrenWithFragment(this, fragment.release(), ec);
}
@@ -209,6 +218,8 @@
void ShadowRoot::setApplyAuthorStyles(bool value)
{
+ GuardOrphanShadowRoot({ });
+
if (m_applyAuthorStyles != value) {
m_applyAuthorStyles = value;
host()->setNeedsStyleRecalc();
@@ -222,6 +233,8 @@
void ShadowRoot::setResetStyleInheritance(bool value)
{
+ GuardOrphanShadowRoot({ });
+
if (value != m_resetStyleInheritance) {
m_resetStyleInheritance = value;
if (attached() && owner())
@@ -275,6 +288,8 @@
void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
+ GuardOrphanShadowRoot({ });
+
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
owner()->invalidateDistribution();
}