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 394038 35a06336b3be69ef131511176334279e3187191c
parent 394037 3e663c47b81610955e90f24c12ca0d9fee5b56dd
child 394039 7a9b07064c28ac88d837c14e3cc85e95a8597aa9
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1341657
milestone54.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 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 =