Bug 1449601. Stop dereferencing a null mIterNode in find code. r=mystor
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 09 Apr 2018 16:30:31 -0400
changeset 412417 51b8010d7a2805f462d2df4d52ec997002efd0be
parent 412416 35b5c25b293e2a7b3d028cb88b5aab8fd7bf02bb
child 412418 f81d6a5b561d8a686b9be38b44ce9eabf325f367
push id101925
push userbzbarsky@mozilla.com
push dateMon, 09 Apr 2018 20:31:32 +0000
treeherdermozilla-inbound@17eff95cd1e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1449601
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1449601. Stop dereferencing a null mIterNode in find code. r=mystor MozReview-Commit-ID: 2buTShJNqFp
dom/base/crashtests/1449601.html
dom/base/crashtests/crashtests.list
toolkit/components/find/nsFind.cpp
toolkit/components/find/nsFind.h
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/1449601.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <script>
+      var blob = new Blob(["foo"], { type: "text/plain" });
+      var url = URL.createObjectURL(blob);
+      var ifr = document.createElement("iframe");
+      ifr.src = url;
+      document.body.appendChild(ifr);
+
+      onload = function() {
+        try { window.find('foo',false,true,true,true,true) } catch(e) { }
+      }
+    </script>
+  </body>
+</html>
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -233,9 +233,10 @@ load 1405771.html
 load 1406109-1.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1324463.html
 pref(dom.webcomponents.customelements.enabled,true) load 1413815.html
 load 1411473.html
 pref(dom.webcomponents.shadowdom.enabled,false) load 1422931.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1419799.html
 skip-if(!browserIsRemote) pref(dom.webcomponents.customelements.enabled,true) pref(dom.disable_open_during_load,false) load 1419902.html # skip on non e10s loads, Bug 1419902
 pref(dom.webcomponents.shadowdom.enabled,true) load 1428053.html
+load 1449601.html
 load 1445670.html
--- a/toolkit/components/find/nsFind.cpp
+++ b/toolkit/components/find/nsFind.cpp
@@ -790,18 +790,18 @@ nsFind::PeekNextChar(nsRange* aSearchRan
   do {
     tc = nullptr;
     NextNode(aSearchRange, aStartPoint, aEndPoint, false);
 
     // Get the text content:
     tc = do_QueryInterface(mIterNode);
 
     // Get the block parent.
-    nsCOMPtr<nsIDOMNode> blockParent;
-    rv = GetBlockParent(mIterNode->AsDOMNode(), getter_AddRefs(blockParent));
+    nsCOMPtr<nsINode> blockParent;
+    rv = GetBlockParent(mIterNode, getter_AddRefs(blockParent));
     if (NS_FAILED(rv))
       return L'\0';
 
     // If out of nodes or in new parent.
     if (!mIterNode || !tc || (blockParent != mLastBlockParent))
       return L'\0';
 
     frag = tc->GetText();
@@ -890,27 +890,23 @@ nsFind::SkipNode(nsIContent* aContent)
     content = content->GetParent();
   }
 
   return false;
 #endif /* HAVE_BIDI_ITERATOR */
 }
 
 nsresult
-nsFind::GetBlockParent(nsIDOMNode* aNode, nsIDOMNode** aParent)
+nsFind::GetBlockParent(nsINode* aNode, nsINode** aParent)
 {
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  // non-nsCOMPtr temporary so we don't keep addrefing/releasing as we
-  // go up the tree.
-  nsINode* curNode = node;
+  nsINode* curNode = aNode;
   while (curNode) {
     nsIContent* parent = curNode->GetParent();
     if (parent && IsBlockNode(parent)) {
-      *aParent = parent->AsDOMNode();
-      NS_ADDREF(*aParent);
+      *aParent = do_AddRef(parent).take();
       return NS_OK;
     }
     curNode = parent;
   }
   return NS_ERROR_FAILURE;
 }
 
 // Call ResetAll before returning, to remove all references to external objects.
@@ -1025,18 +1021,18 @@ nsFind::Find(const char16_t* aPatText, n
         // to search again (from beginning/end).
         ResetAll();
         return NS_OK;
       }
 
       // We have a new text content. If its block parent is different from the
       // block parent of the last text content, then we need to clear the match
       // since we don't want to find across block boundaries.
-      nsCOMPtr<nsIDOMNode> blockParent;
-      GetBlockParent(mIterNode->AsDOMNode(), getter_AddRefs(blockParent));
+      nsCOMPtr<nsINode> blockParent;
+      GetBlockParent(mIterNode, getter_AddRefs(blockParent));
 #ifdef DEBUG_FIND
       printf("New node: old blockparent = %p, new = %p\n",
              (void*)mLastBlockParent.get(), (void*)blockParent.get());
 #endif
       if (blockParent != mLastBlockParent) {
 #ifdef DEBUG_FIND
         printf("Different block parent!\n");
 #endif
--- a/toolkit/components/find/nsFind.h
+++ b/toolkit/components/find/nsFind.h
@@ -45,18 +45,18 @@ protected:
   // Use "find entire words" mode by setting to a word breaker or null, to
   // disable "entire words" mode.
   RefPtr<mozilla::intl::WordBreaker> mWordBreaker;
 
   int32_t mIterOffset;
   nsCOMPtr<nsINode> mIterNode;
 
   // Last block parent, so that we will notice crossing block boundaries:
-  nsCOMPtr<nsIDOMNode> mLastBlockParent;
-  nsresult GetBlockParent(nsIDOMNode* aNode, nsIDOMNode** aParent);
+  nsCOMPtr<nsINode> mLastBlockParent;
+  nsresult GetBlockParent(nsINode* aNode, nsINode** aParent);
 
   // Utility routines:
   bool IsBlockNode(nsIContent* aNode);
   bool SkipNode(nsIContent* aNode);
   bool IsVisibleNode(nsINode* aNode);
 
   // Move in the right direction for our search:
   nsresult NextNode(nsRange* aSearchRange,