Bug 1038756: Callsites creating a channel in /docshell/ (r=bz)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Sun, 21 Sep 2014 09:40:48 -0700
changeset 206511 7fc6512d34b18a00c0c145c27087496237c6b028
parent 206510 2d6e88e962a7f6acbb083002d5c8cdb9f19f25f5
child 206512 de85d97eac27680338f398df85f3f281a071d200
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbz
bugs1038756
milestone35.0a1
Bug 1038756: Callsites creating a channel in /docshell/ (r=bz)
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -107,16 +107,17 @@
 #include "nsITimer.h"
 #include "nsISHistoryInternal.h"
 #include "nsIPrincipal.h"
 #include "nsNullPrincipal.h"
 #include "nsISHEntry.h"
 #include "nsIWindowWatcher.h"
 #include "nsIPromptFactory.h"
 #include "nsITransportSecurityInfo.h"
+#include "nsINode.h"
 #include "nsINSSErrorsService.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIApplicationCacheContainer.h"
 #include "nsStreamUtils.h"
 #include "nsIController.h"
 #include "nsPICommandUpdater.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIWebBrowserChrome3.h"
@@ -9173,16 +9174,39 @@ private:
  */
 bool
 nsDocShell::JustStartedNetworkLoad()
 {
     return mDocumentRequest &&
            mDocumentRequest != GetCurrentDocChannel();
 }
 
+nsresult
+nsDocShell::CreatePrincipalFromReferrer(nsIURI*        aReferrer,
+                                        nsIPrincipal** outPrincipal)
+{
+  nsresult rv;
+  nsCOMPtr<nsIScriptSecurityManager> secMan =
+    do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  uint32_t appId;
+  rv = GetAppId(&appId);
+  NS_ENSURE_SUCCESS(rv, rv);
+  bool isInBrowserElement;
+  rv = GetIsInBrowserElement(&isInBrowserElement);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = secMan->GetAppCodebasePrincipal(aReferrer,
+                                       appId,
+                                       isInBrowserElement,
+                                       outPrincipal);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsDocShell::InternalLoad(nsIURI * aURI,
                          nsIURI * aReferrer,
                          nsISupports * aOwner,
                          uint32_t aFlags,
                          const char16_t *aWindowTarget,
                          const char* aTypeHint,
                          const nsAString& aFileName,
@@ -9291,22 +9315,18 @@ nsDocShell::InternalLoad(nsIURI * aURI,
     nsISupports* context = requestingElement;
     if (!context) {
         context = ToSupports(mScriptGlobal);
     }
 
     // XXXbz would be nice to know the loading principal here... but we don't
     nsCOMPtr<nsIPrincipal> loadingPrincipal = do_QueryInterface(aOwner);
     if (!loadingPrincipal && aReferrer) {
-        nsCOMPtr<nsIScriptSecurityManager> secMan =
-            do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = secMan->GetSimpleCodebasePrincipal(aReferrer,
-                                                getter_AddRefs(loadingPrincipal));
+      rv = CreatePrincipalFromReferrer(aReferrer, getter_AddRefs(loadingPrincipal));
+      NS_ENSURE_SUCCESS(rv, rv);
     }
 
     rv = NS_CheckContentLoadPolicy(contentType,
                                    aURI,
                                    loadingPrincipal,
                                    context,
                                    EmptyCString(), //mime guess
                                    nullptr,         //extra
@@ -9962,17 +9982,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
     nsCOMPtr<nsIRequest> req;
     rv = DoURILoad(aURI, aReferrer,
                    !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
                    owner, aTypeHint, aFileName, aPostData, aHeadersData,
                    aFirstParty, aDocShell, getter_AddRefs(req),
                    (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
                    (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
                    (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0,
-                   srcdoc, aBaseURI);
+                   srcdoc, aBaseURI, contentType);
     if (req && aRequest)
         NS_ADDREF(*aRequest = req);
 
     if (NS_FAILED(rv)) {
         nsCOMPtr<nsIChannel> chan(do_QueryInterface(req));
         DisplayLoadError(rv, aURI, nullptr, chan);
     }
 
@@ -10042,17 +10062,18 @@ nsDocShell::DoURILoad(nsIURI * aURI,
                       nsIInputStream * aHeadersData,
                       bool aFirstParty,
                       nsIDocShell ** aDocShell,
                       nsIRequest ** aRequest,
                       bool aIsNewWindowTarget,
                       bool aBypassClassifier,
                       bool aForceAllowCookies,
                       const nsAString &aSrcdoc,
-                      nsIURI * aBaseURI)
+                      nsIURI * aBaseURI,
+                      nsContentPolicyType aContentPolicyType)
 {
 #ifdef MOZ_VISUAL_EVENT_TRACER
     nsAutoCString urlSpec;
     aURI->GetAsciiSpec(urlSpec);
     MOZ_EVENT_TRACER_NAME_OBJECT(this, urlSpec.BeginReading());
     MOZ_EVENT_TRACER_EXEC(this, "docshell::pageload");
 #endif
 
@@ -10113,24 +10134,46 @@ nsDocShell::DoURILoad(nsIURI * aURI,
             nestedURI = do_QueryInterface(tempURI);
         }
     }
 
     // open a channel for the url
     nsCOMPtr<nsIChannel> channel;
 
     bool isSrcdoc = !aSrcdoc.IsVoid();
+
+    nsCOMPtr<nsINode> requestingNode;
+    if (mScriptGlobal) {
+      requestingNode = mScriptGlobal->GetFrameElementInternal();
+      if (!requestingNode) {
+        requestingNode = mScriptGlobal->GetExtantDoc();
+      }
+    }
+    nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(aOwner);
+    if (!requestingPrincipal && aReferrerURI) {
+      rv = CreatePrincipalFromReferrer(aReferrerURI,
+                                       getter_AddRefs(requestingPrincipal));
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+    else {
+      requestingPrincipal = nsContentUtils::GetSystemPrincipal();
+    }
+
     if (!isSrcdoc) {
-        rv = NS_NewChannel(getter_AddRefs(channel),
-                           aURI,
-                           nullptr,
-                           nullptr,
-                           static_cast<nsIInterfaceRequestor *>(this),
-                           loadFlags,
-                           channelPolicy);
+        rv = NS_NewChannelInternal(getter_AddRefs(channel),
+                                   aURI,
+                                   requestingNode,
+                                   requestingPrincipal,
+                                   nsILoadInfo::SEC_NORMAL,
+                                   aContentPolicyType,
+                                   channelPolicy,
+                                   nullptr,   // loadGroup
+                                   static_cast<nsIInterfaceRequestor*>(this),
+                                   loadFlags);
+
         if (NS_FAILED(rv)) {
             if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
                 // This is a uri with a protocol scheme we don't know how
                 // to handle.  Embedders might still be interested in
                 // handling the load, though, so we fire a notification
                 // before throwing the load away.
                 bool abort = false;
                 nsresult rv2 = mContentListener->OnStartURIOpen(aURI, &abort);
@@ -10168,16 +10211,24 @@ nsDocShell::DoURILoad(nsIURI * aURI,
                                           aSrcdoc,
                                           NS_LITERAL_CSTRING("text/html"),
                                           true);
             NS_ENSURE_SUCCESS(rv, rv);
             nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(channel);
             MOZ_ASSERT(isc);
             isc->SetBaseURI(aBaseURI);
         }
+        // NS_NewInputStreamChannel does not yet attach the loadInfo in nsNetutil.h,
+        // hence we have to manually attach the loadInfo for that channel.
+        nsCOMPtr<nsILoadInfo> loadInfo =
+          new LoadInfo(requestingPrincipal,
+                       requestingNode,
+                       nsILoadInfo::SEC_NORMAL,
+                       aContentPolicyType);
+        channel->SetLoadInfo(loadInfo);
     }
 
     nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
         do_QueryInterface(channel);
     if (appCacheChannel) {
         // Any document load should not inherit application cache.
         appCacheChannel->SetInheritApplicationCache(false);
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -4,16 +4,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDocShell_h__
 #define nsDocShell_h__
 
 #include "nsITimer.h"
+#include "nsContentPolicyUtils.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIBaseWindow.h"
 #include "nsIScrollable.h"
 #include "nsITextScroll.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIDOMStorageManager.h"
 #include "nsDocLoader.h"
@@ -312,17 +313,18 @@ protected:
                                nsIInputStream * aHeadersData,
                                bool firstParty,
                                nsIDocShell ** aDocShell,
                                nsIRequest ** aRequest,
                                bool aIsNewWindowTarget,
                                bool aBypassClassifier,
                                bool aForceAllowCookies,
                                const nsAString &aSrcdoc,
-                               nsIURI * baseURI);
+                               nsIURI * baseURI,
+                               nsContentPolicyType aContentPolicyType);
     NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData, 
                                   nsIChannel * aChannel);
     virtual nsresult DoChannelLoad(nsIChannel * aChannel,
                                    nsIURILoader * aURILoader,
                                    bool aBypassClassifier);
 
     nsresult ScrollToAnchor(nsACString & curHash, nsACString & newHash,
                             uint32_t aLoadType);
@@ -693,16 +695,19 @@ protected:
         explicit RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {}
         void Revoke() { mDocShell = nullptr; }
     private:
         nsRefPtr<nsDocShell> mDocShell;
     };
 
     bool JustStartedNetworkLoad();
 
+    nsresult CreatePrincipalFromReferrer(nsIURI*        aReferrer,
+                                         nsIPrincipal** outPrincipal);
+
     enum FrameType {
         eFrameTypeRegular,
         eFrameTypeBrowser,
         eFrameTypeApp
     };
 
     static const nsCString FrameTypeToString(FrameType aFrameType)
     {