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 330995 59231900a5a5dc916ac76a333f40776d63540f8a
parent 330994 f054c2480618ee6ac9603c8c6cf10b1eeeab2cfe
child 330996 573ce84e754770db26e9c1d19793b1382c3c8891
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking, ckerschb
bugs1105556
milestone48.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 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;