Bug 1105556 - Allow loadInfo->loadingNode and loadInfo->loadingPrincipal to be null for TYPE_DOCUMENT loads. r=sicking, ckerschb
authorTanvi Vyas <tanvi@mozilla.com>
Wed, 13 Apr 2016 16:30:16 -0700
changeset 316898 59231900a5a5dc916ac76a333f40776d63540f8a
parent 316897 f054c2480618ee6ac9603c8c6cf10b1eeeab2cfe
child 316899 573ce84e754770db26e9c1d19793b1382c3c8891
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking, ckerschb
bugs1105556
milestone48.0a1
Bug 1105556 - Allow loadInfo->loadingNode and loadInfo->loadingPrincipal to be null for TYPE_DOCUMENT loads. r=sicking, ckerschb
ipc/glue/BackgroundUtils.cpp
netwerk/base/LoadInfo.cpp
netwerk/base/LoadInfo.h
netwerk/base/moz.build
netwerk/base/nsIOService.cpp
netwerk/ipc/NeckoChannelParams.ipdlh
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -210,20 +210,24 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
 {
   if (!aLoadInfo) {
     // if there is no loadInfo, then there is nothing to serialize
     *aOptionalLoadInfoArgs = void_t();
     return NS_OK;
   }
 
   nsresult rv = NS_OK;
-  PrincipalInfo requestingPrincipalInfo;
-  rv = PrincipalToPrincipalInfo(aLoadInfo->LoadingPrincipal(),
-                                &requestingPrincipalInfo);
-  NS_ENSURE_SUCCESS(rv, rv);
+  OptionalPrincipalInfo loadingPrincipalInfo = mozilla::void_t();
+  if (aLoadInfo->LoadingPrincipal()) {
+    PrincipalInfo loadingPrincipalInfoTemp;
+    rv = PrincipalToPrincipalInfo(aLoadInfo->LoadingPrincipal(),
+                                  &loadingPrincipalInfoTemp);
+    NS_ENSURE_SUCCESS(rv, rv);
+    loadingPrincipalInfo = loadingPrincipalInfoTemp;
+  }
 
   PrincipalInfo triggeringPrincipalInfo;
   rv = PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(),
                                 &triggeringPrincipalInfo);
 
   nsTArray<PrincipalInfo> redirectChainIncludingInternalRedirects;
   for (const nsCOMPtr<nsIPrincipal>& principal : aLoadInfo->RedirectChainIncludingInternalRedirects()) {
     rv = PrincipalToPrincipalInfo(principal, redirectChainIncludingInternalRedirects.AppendElement());
@@ -233,17 +237,17 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
   nsTArray<PrincipalInfo> redirectChain;
   for (const nsCOMPtr<nsIPrincipal>& principal : aLoadInfo->RedirectChain()) {
     rv = PrincipalToPrincipalInfo(principal, redirectChain.AppendElement());
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   *aOptionalLoadInfoArgs =
     LoadInfoArgs(
-      requestingPrincipalInfo,
+      loadingPrincipalInfo,
       triggeringPrincipalInfo,
       aLoadInfo->GetSecurityFlags(),
       aLoadInfo->InternalContentPolicyType(),
       static_cast<uint32_t>(aLoadInfo->GetTainting()),
       aLoadInfo->GetUpgradeInsecureRequests(),
       aLoadInfo->GetVerifySignedContent(),
       aLoadInfo->GetEnforceSRI(),
       aLoadInfo->GetInnerWindowID(),
@@ -270,18 +274,22 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
     *outLoadInfo = nullptr;
     return NS_OK;
   }
 
   const LoadInfoArgs& loadInfoArgs =
     aOptionalLoadInfoArgs.get_LoadInfoArgs();
 
   nsresult rv = NS_OK;
-  nsCOMPtr<nsIPrincipal> requestingPrincipal =
-    PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo(), &rv);
+  nsCOMPtr<nsIPrincipal> loadingPrincipal;
+  if (loadInfoArgs.requestingPrincipalInfo().type() != OptionalPrincipalInfo::Tvoid_t) {
+    loadingPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo(), &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIPrincipal> triggeringPrincipal =
     PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsTArray<nsCOMPtr<nsIPrincipal>> redirectChainIncludingInternalRedirects;
   for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChainIncludingInternalRedirects()) {
     nsCOMPtr<nsIPrincipal> redirectedPrincipal =
@@ -294,17 +302,17 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
   for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChain()) {
     nsCOMPtr<nsIPrincipal> redirectedPrincipal =
       PrincipalInfoToPrincipal(principalInfo, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     redirectChain.AppendElement(redirectedPrincipal.forget());
   }
 
   nsCOMPtr<nsILoadInfo> loadInfo =
-    new mozilla::LoadInfo(requestingPrincipal,
+    new mozilla::LoadInfo(loadingPrincipal,
                           triggeringPrincipal,
                           loadInfoArgs.securityFlags(),
                           loadInfoArgs.contentPolicyType(),
                           static_cast<LoadTainting>(loadInfoArgs.tainting()),
                           loadInfoArgs.upgradeInsecureRequests(),
                           loadInfoArgs.verifySignedContent(),
                           loadInfoArgs.enforceSRI(),
                           loadInfoArgs.innerWindowID(),
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -13,16 +13,17 @@
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIFrameLoader.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISupportsImpl.h"
 #include "nsISupportsUtils.h"
 #include "nsContentUtils.h"
+#include "nsDocShell.h"
 #include "nsGlobalWindow.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 static void
 InheritOriginAttributes(nsIPrincipal* aLoadingPrincipal, NeckoOriginAttributes& aAttrs)
@@ -54,16 +55,19 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mEnforceSecurity(false)
   , mInitialSecurityCheckDone(false)
   , mIsThirdPartyContext(false)
   , mForcePreflight(false)
   , mIsPreflight(false)
 {
   MOZ_ASSERT(mLoadingPrincipal);
   MOZ_ASSERT(mTriggeringPrincipal);
+  // This constructor shouldn't be used for TYPE_DOCUMENT loads that don't
+  // have a loadingPrincipal
+  MOZ_ASSERT(mInternalContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT);
 
   // TODO(bug 1259873): Above, we initialize mIsThirdPartyContext to false meaning
   // that consumers of LoadInfo that don't pass a context or pass a context from
   // which we can't find a window will default to assuming that they're 1st
   // party. It would be nice if we could default "safe" and assume that we are
   // 3rd party until proven otherwise.
 
   // if consumers pass both, aLoadingContext and aLoadingPrincipal
@@ -129,21 +133,24 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
         loadInfo->GetVerifySignedContent(&mEnforceSRI);
       }
     }
   }
 
   InheritOriginAttributes(mLoadingPrincipal, mOriginAttributes);
 }
 
+/* Constructor takes an outer window, but no loadingNode or loadingPrincipal.
+ * This constructor should only be used for TYPE_DOCUMENT loads, since they
+ * have a null loadingNode and loadingPrincipal.
+*/
 LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
-                   nsIPrincipal* aLoadingPrincipal,
                    nsIPrincipal* aTriggeringPrincipal,
                    nsSecurityFlags aSecurityFlags)
-  : mLoadingPrincipal(aLoadingPrincipal)
+  : mLoadingPrincipal(nullptr)
   , mTriggeringPrincipal(aTriggeringPrincipal)
   , mSecurityFlags(aSecurityFlags)
   , mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT)
   , mTainting(LoadTainting::Basic)
   , mUpgradeInsecureRequests(false)
   , mVerifySignedContent(false)
   , mEnforceSRI(false)
   , mInnerWindowID(0)
@@ -153,31 +160,37 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
   , mInitialSecurityCheckDone(false)
   , mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
   , mForcePreflight(false)
   , mIsPreflight(false)
 {
   // Top-level loads are never third-party
   // Grab the information we can out of the window.
   MOZ_ASSERT(aOuterWindow);
+  MOZ_ASSERT(mTriggeringPrincipal);
 
   // if the load is sandboxed, we can not also inherit the principal
   if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
     mSecurityFlags ^= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
 
   // NB: Ignore the current inner window since we're navigating away from it.
   mOuterWindowID = aOuterWindow->WindowID();
 
   // TODO We can have a parent without a frame element in some cases dealing
   // with the hidden window.
   nsCOMPtr<nsPIDOMWindowOuter> parent = aOuterWindow->GetScriptableParent();
   mParentOuterWindowID = parent ? parent->WindowID() : 0;
 
-  InheritOriginAttributes(mLoadingPrincipal, mOriginAttributes);
+  // get the docshell from the outerwindow, and then get the originattributes
+  nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
+  MOZ_ASSERT(docShell);
+  const DocShellOriginAttributes attrs =
+    nsDocShell::Cast(docShell)->GetOriginAttributes();
+  mOriginAttributes.InheritFromDocShellToNecko(attrs);
 }
 
 LoadInfo::LoadInfo(const LoadInfo& rhs)
   : mLoadingPrincipal(rhs.mLoadingPrincipal)
   , mTriggeringPrincipal(rhs.mTriggeringPrincipal)
   , mLoadingContext(rhs.mLoadingContext)
   , mSecurityFlags(rhs.mSecurityFlags)
   , mInternalContentPolicyType(rhs.mInternalContentPolicyType)
@@ -235,17 +248,18 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mEnforceSecurity(aEnforceSecurity)
   , mInitialSecurityCheckDone(aInitialSecurityCheckDone)
   , mIsThirdPartyContext(aIsThirdPartyContext)
   , mOriginAttributes(aOriginAttributes)
   , mCorsUnsafeHeaders(aCorsUnsafeHeaders)
   , mForcePreflight(aForcePreflight)
   , mIsPreflight(aIsPreflight)
 {
-  MOZ_ASSERT(mLoadingPrincipal);
+  // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
+  MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
   MOZ_ASSERT(mTriggeringPrincipal);
 
   mRedirectChainIncludingInternalRedirects.SwapElements(
     aRedirectChainIncludingInternalRedirects);
 
   mRedirectChain.SwapElements(aRedirectChain);
 }
 
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -49,19 +49,19 @@ public:
 
   // aLoadingPrincipal MUST NOT BE NULL.
   LoadInfo(nsIPrincipal* aLoadingPrincipal,
            nsIPrincipal* aTriggeringPrincipal,
            nsINode* aLoadingContext,
            nsSecurityFlags aSecurityFlags,
            nsContentPolicyType aContentPolicyType);
 
-  // Constructor used for TYPE_DOCUMENT loads with no reasonable loadingNode.
+  // Constructor used for TYPE_DOCUMENT loads which have no reasonable
+  // loadingNode or loadingPrincipal
   LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
-           nsIPrincipal* aLoadingPrincipal,
            nsIPrincipal* aTriggeringPrincipal,
            nsSecurityFlags aSecurityFlags);
 
   // create an exact copy of the loadinfo
   already_AddRefed<nsILoadInfo> Clone() const;
   // creates a copy of the loadinfo which is appropriate to use for a
   // separate request. I.e. not for a redirect or an inner channel, but
   // when a separate request is made with the same security properties.
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -290,16 +290,17 @@ EXTRA_JS_MODULES += [
     'NetUtil.jsm',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
+    '/docshell/base',
     '/dom/base',
     '/netwerk/protocol/http'
 ]
 
 if 'rtsp' in CONFIG['NECKO_PROTOCOLS']:
     LOCAL_INCLUDES += [
         '/netwerk/protocol/rtsp/controller',
         '/netwerk/protocol/rtsp/rtsp',
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -862,19 +862,24 @@ nsIOService::NewChannelFromURIWithProxyF
     // might still call NewChannelFromURIWithProxyFlags() which forwards
     // its calls to NewChannelFromURIWithProxyFlags2 using *null* values
     // as the arguments for aLoadingNode, aLoadingPrincipal, and also
     // aTriggeringPrincipal.
     // We do not want to break those addons, hence we only create a Loadinfo
     // if 'aLoadingNode' or 'aLoadingPrincipal' are provided. Note, that
     // either aLoadingNode or aLoadingPrincipal is required to succesfully
     // create a LoadInfo object.
+    // Except in the case of top level TYPE_DOCUMENT loads, where the
+    // loadingNode and loadingPrincipal are allowed to have null values.
     nsCOMPtr<nsILoadInfo> loadInfo;
 
-    if (aLoadingNode || aLoadingPrincipal) {
+    // TYPE_DOCUMENT loads don't require a loadingNode or principal, but other
+    // types do.
+    if (aLoadingNode || aLoadingPrincipal ||
+        aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) {
       nsCOMPtr<nsINode> loadingNode(do_QueryInterface(aLoadingNode));
       loadInfo = new mozilla::LoadInfo(aLoadingPrincipal,
                                        aTriggeringPrincipal,
                                        loadingNode,
                                        aSecurityFlags,
                                        aContentPolicyType);
     }
     NS_ASSERTION(loadInfo, "Please pass security info when creating a channel");
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -22,36 +22,36 @@ namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
 // LoadInfo IPDL structs
 //-----------------------------------------------------------------------------
 
 struct LoadInfoArgs
 {
-  PrincipalInfo    requestingPrincipalInfo;
-  PrincipalInfo    triggeringPrincipalInfo;
-  uint32_t         securityFlags;
-  uint32_t         contentPolicyType;
-  uint32_t         tainting;
-  bool             upgradeInsecureRequests;
-  bool             verifySignedContent;
-  bool             enforceSRI;
-  uint64_t         innerWindowID;
-  uint64_t         outerWindowID;
-  uint64_t         parentOuterWindowID;
-  bool             enforceSecurity;
-  bool             initialSecurityCheckDone;
-  bool             isInThirdPartyContext;
+  OptionalPrincipalInfo requestingPrincipalInfo;
+  PrincipalInfo         triggeringPrincipalInfo;
+  uint32_t              securityFlags;
+  uint32_t              contentPolicyType;
+  uint32_t              tainting;
+  bool                  upgradeInsecureRequests;
+  bool                  verifySignedContent;
+  bool                  enforceSRI;
+  uint64_t              innerWindowID;
+  uint64_t              outerWindowID;
+  uint64_t              parentOuterWindowID;
+  bool                  enforceSecurity;
+  bool                  initialSecurityCheckDone;
+  bool                  isInThirdPartyContext;
   NeckoOriginAttributes originAttributes;
-  PrincipalInfo[]  redirectChainIncludingInternalRedirects;
-  PrincipalInfo[]  redirectChain;
-  nsCString[]      corsUnsafeHeaders;
-  bool             forcePreflight;
-  bool             isPreflight;
+  PrincipalInfo[]       redirectChainIncludingInternalRedirects;
+  PrincipalInfo[]       redirectChain;
+  nsCString[]           corsUnsafeHeaders;
+  bool                  forcePreflight;
+  bool                  isPreflight;
 };
 
 /**
  * Not every channel necessarily has a loadInfo attached.
  */
 union OptionalLoadInfoArgs
 {
   void_t;