Bug 1420547: Add assertions for the assumptions we're making. r?bz draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 11 Dec 2017 10:14:36 +0100
changeset 713801 0efbef6fe63d6435aa0cb4d6ee4e24e1ccc000e8
parent 713800 d33d7bb985f4c1c86a996c8d354e7fdb1e5bfd8f
child 744432 8bda8b53ee499f61a51525259193cf3ff88479da
push id93751
push userbmo:emilio@crisal.io
push dateWed, 20 Dec 2017 23:52:04 +0000
reviewersbz
bugs1420547
milestone59.0a1
Bug 1420547: Add assertions for the assumptions we're making. r?bz MozReview-Commit-ID: 8CVtclXLgzH
dom/base/nsNodeUtils.cpp
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -43,25 +43,33 @@ using namespace mozilla::dom;
 using mozilla::AutoJSContext;
 
 enum class IsRemoveNotification
 {
   Yes,
   No,
 };
 
+#ifdef DEBUG
+#define COMPOSED_DOC_DECL \
+  const bool wasInComposedDoc = !!node->GetComposedDoc();
+#else
+#define COMPOSED_DOC_DECL
+#endif
+
 // This macro expects the ownerDocument of content_ to be in scope as
 // |nsIDocument* doc|
 #define IMPL_MUTATION_NOTIFICATION(func_, content_, params_, remove_)       \
   PR_BEGIN_MACRO                                                            \
   bool needsEnterLeave = doc->MayHaveDOMMutationObservers();                \
   if (needsEnterLeave) {                                                    \
     nsDOMMutationObserver::EnterMutationHandling();                         \
   }                                                                         \
   nsINode* node = content_;                                                 \
+  COMPOSED_DOC_DECL                                                         \
   NS_ASSERTION(node->OwnerDoc() == doc, "Bogus document");                  \
   if (remove_ == IsRemoveNotification::Yes && node->GetComposedDoc()) {     \
     if (nsIPresShell* shell = doc->GetObservingShell()) {                   \
       shell->func_ params_;                                                 \
     }                                                                       \
   }                                                                         \
   doc->BindingManager()->func_ params_;                                     \
   nsINode* last;                                                            \
@@ -74,16 +82,22 @@ enum class IsRemoveNotification
     }                                                                       \
     last = node;                                                            \
     if (ShadowRoot* shadow = ShadowRoot::FromNode(node)) {                  \
       node = shadow->GetHost();                                             \
     } else {                                                                \
       node = node->GetParentNode();                                         \
     }                                                                       \
   } while (node);                                                           \
+  /* Whitelist NativeAnonymousChildListChange removal notifications from    \
+   * the assertion since it runs from UnbindFromTree, and thus we don't     \
+   * reach the document, but doesn't matter. */                             \
+  MOZ_ASSERT((last == doc) == wasInComposedDoc ||                           \
+             (remove_ == IsRemoveNotification::Yes &&                       \
+              !strcmp(#func_, "NativeAnonymousChildListChange")));          \
   if (remove_ == IsRemoveNotification::No && last == doc) {                 \
     if (nsIPresShell* shell = doc->GetObservingShell()) {                   \
       shell->func_ params_;                                                 \
     }                                                                       \
   }                                                                         \
   if (needsEnterLeave) {                                                    \
     nsDOMMutationObserver::LeaveMutationHandling();                         \
   }                                                                         \
@@ -181,19 +195,21 @@ nsNodeUtils::ContentAppended(nsIContent*
                              IsRemoveNotification::No);
 }
 
 void
 nsNodeUtils::NativeAnonymousChildListChange(nsIContent* aContent,
                                             bool aIsRemove)
 {
   nsIDocument* doc = aContent->OwnerDoc();
+  auto isRemove = aIsRemove
+    ? IsRemoveNotification::Yes : IsRemoveNotification::No;
   IMPL_MUTATION_NOTIFICATION(NativeAnonymousChildListChange, aContent,
                             (doc, aContent, aIsRemove),
-                            IsRemoveNotification::No);
+                            isRemove);
 }
 
 void
 nsNodeUtils::ContentInserted(nsINode* aContainer,
                              nsIContent* aChild)
 {
   NS_PRECONDITION(aContainer->IsContent() ||
                   aContainer->IsNodeOfType(nsINode::eDOCUMENT),