Bug 1341657 - Properly deal with not having a frame element in nsDocShell::InternalLoad(); r=smaug
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 24 Feb 2017 19:30:04 -0500
changeset 374088 35a06336b3be69ef131511176334279e3187191c
parent 374087 3e663c47b81610955e90f24c12ca0d9fee5b56dd
child 374089 7a9b07064c28ac88d837c14e3cc85e95a8597aa9
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1341657
milestone54.0a1
Bug 1341657 - Properly deal with not having a frame element in nsDocShell::InternalLoad(); r=smaug
docshell/base/crashtests/1341657.html
docshell/base/crashtests/crashtests.list
docshell/base/nsDocShell.cpp
new file mode 100644
--- /dev/null
+++ b/docshell/base/crashtests/1341657.html
@@ -0,0 +1,14 @@
+<html>
+    <head>
+        <script>
+            o1 = document.createElement("script");
+            o2 = document.implementation.createDocument('', '', null);
+            o3 = document.createElement("iframe");
+            document.documentElement.appendChild(o3);
+            o4 = o3.contentWindow;
+            o5 = document.createTextNode('o2.adoptNode(o3); try { o4.location = "" } catch(e) {}');
+            o1.appendChild(o5);
+            document.documentElement.appendChild(o1);
+        </script>
+    </head>
+</html>
\ No newline at end of file
--- a/docshell/base/crashtests/crashtests.list
+++ b/docshell/base/crashtests/crashtests.list
@@ -9,8 +9,9 @@ load 436900-1.html
 asserts(0-1) load 436900-2.html # bug 566159
 load 500328-1.html
 load 514779-1.xhtml
 load 614499-1.html
 load 678872-1.html
 skip-if(Android) pref(dom.disable_open_during_load,false) load 914521.html
 pref(browser.send_pings,true) load 1257730-1.html
 load 1331295.html
+load 1341657.html
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9887,19 +9887,24 @@ nsDocShell::InternalLoad(nsIURI* aURI,
   // 2. AND aWindowTarget is not a new window, nor a top-level window.
   //
   // This variable will be used when we call NS_CheckContentLoadPolicy, and
   // later when we call DoURILoad.
   uint32_t contentType;
   if (IsFrame() && !isTargetTopLevelDocShell) {
     nsCOMPtr<Element> requestingElement =
       mScriptGlobal->AsOuter()->GetFrameElementInternal();
-    NS_ASSERTION(requestingElement, "A frame but no DOM element!?");
-    contentType = requestingElement->IsHTMLElement(nsGkAtoms::iframe) ?
-      nsIContentPolicy::TYPE_INTERNAL_IFRAME : nsIContentPolicy::TYPE_INTERNAL_FRAME;
+    if (requestingElement) {
+      contentType = requestingElement->IsHTMLElement(nsGkAtoms::iframe) ?
+        nsIContentPolicy::TYPE_INTERNAL_IFRAME : nsIContentPolicy::TYPE_INTERNAL_FRAME;
+    } else {
+      // If we have lost our frame element by now, just assume we're
+      // an iframe since that's more common.
+      contentType = nsIContentPolicy::TYPE_INTERNAL_IFRAME;
+    }
   } else {
     contentType = nsIContentPolicy::TYPE_DOCUMENT;
     isTargetTopLevelDocShell = true;
   }
 
   // If there's no targetDocShell, that means we are about to create a new window,
   // perform a content policy check before creating the window.
   if (!targetDocShell) {
@@ -9919,23 +9924,25 @@ nsDocShell::InternalLoad(nsIURI* aURI,
         requestingElement = mScriptGlobal->AsOuter()->GetFrameElementInternal();
         requestingContext = requestingElement;
       }
     } else {
       requestingElement = mScriptGlobal->AsOuter()->GetFrameElementInternal();
       requestingContext = requestingElement;
 
 #ifdef DEBUG
-      // Get the docshell type for requestingElement.
-      nsCOMPtr<nsIDocument> requestingDoc = requestingElement->OwnerDoc();
-      nsCOMPtr<nsIDocShell> elementDocShell = requestingDoc->GetDocShell();
-
-      // requestingElement docshell type = current docshell type.
-      MOZ_ASSERT(mItemType == elementDocShell->ItemType(),
-                "subframes should have the same docshell type as their parent");
+      if (requestingElement) {
+        // Get the docshell type for requestingElement.
+        nsCOMPtr<nsIDocument> requestingDoc = requestingElement->OwnerDoc();
+        nsCOMPtr<nsIDocShell> elementDocShell = requestingDoc->GetDocShell();
+
+        // requestingElement docshell type = current docshell type.
+        MOZ_ASSERT(mItemType == elementDocShell->ItemType(),
+                  "subframes should have the same docshell type as their parent");
+      }
 #endif
     }
 
     // Since Content Policy checks are performed within docShell as well as
     // the ContentSecurityManager we need a reliable way to let certain
     // nsIContentPolicy consumers ignore duplicate calls. Let's use the 'extra'
     // argument to pass a specific identifier.
     nsCOMPtr<nsISupportsString> extraStr =