Bug 1340652 P1 Assert principal URL matches final worker script URL. r=baku
authorBen Kelly <ben@wanderview.com>
Thu, 23 Feb 2017 10:54:41 -0500
changeset 373627 513ff147aa6c87a74fee27bd1ab7b0ac3dc095f3
parent 373626 e71b6d1907a868c5aa67913755de36dc151a8cb3
child 373628 55bc3b41baab92e204468c2307e2998102bd6305
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)
reviewersbaku
bugs1340652
milestone54.0a1
Bug 1340652 P1 Assert principal URL matches final worker script URL. r=baku
dom/workers/ScriptLoader.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/Workers.h
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -617,16 +617,20 @@ private:
     MOZ_ASSERT(aIndex < mLoadInfos.Length());
     ScriptLoadInfo& loadInfo = mLoadInfos[aIndex];
 
     loadInfo.mLoadResult = aRv;
 
     MOZ_ASSERT(!loadInfo.mLoadingFinished);
     loadInfo.mLoadingFinished = true;
 
+    if (IsMainWorkerScript() && NS_SUCCEEDED(aRv)) {
+      MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate->PrincipalURIMatchesScriptURL());
+    }
+
     MaybeExecuteFinishedScripts(aIndex);
   }
 
   void
   MaybeExecuteFinishedScripts(uint32_t aIndex)
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(aIndex < mLoadInfos.Length());
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1980,16 +1980,67 @@ WorkerLoadInfo::FinalChannelPrincipalIsV
 
 bool
 WorkerLoadInfo::PrincipalIsValid() const
 {
   return mPrincipal && mPrincipalInfo &&
          mPrincipalInfo->type() != PrincipalInfo::T__None &&
          mPrincipalInfo->type() <= PrincipalInfo::T__Last;
 }
+
+bool
+WorkerLoadInfo::PrincipalURIMatchesScriptURL()
+{
+  AssertIsOnMainThread();
+
+  nsAutoCString scheme;
+  nsresult rv = mBaseURI->GetScheme(scheme);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  // A system principal must either be a blob URL or a resource JSM.
+  if (mPrincipal->GetIsSystemPrincipal()) {
+    if (scheme == NS_LITERAL_CSTRING("blob")) {
+      return true;
+    }
+
+    bool isResource = false;
+    nsresult rv = NS_URIChainHasFlags(mBaseURI,
+                                      nsIProtocolHandler::URI_IS_UI_RESOURCE,
+                                      &isResource);
+    NS_ENSURE_SUCCESS(rv, false);
+
+    return isResource;
+  }
+
+  // A null principal can occur for a data URL worker script or a blob URL
+  // worker script from a sandboxed iframe.
+  if (mPrincipal->GetIsNullPrincipal()) {
+    return scheme == NS_LITERAL_CSTRING("data") ||
+           scheme == NS_LITERAL_CSTRING("blob");
+  }
+
+  // The principal for a blob: URL worker script does not have a matching URL.
+  // This is likely a bug in our referer setting logic, but exempt it for now.
+  // This is another reason we should fix bug 1340694 so that referer does not
+  // depend on the principal URI.
+  if (scheme == NS_LITERAL_CSTRING("blob")) {
+    return true;
+  }
+
+  nsCOMPtr<nsIURI> principalURI;
+  rv = mPrincipal->GetURI(getter_AddRefs(principalURI));
+  NS_ENSURE_SUCCESS(rv, false);
+  NS_ENSURE_TRUE(principalURI, false);
+
+  bool equal = false;
+  rv = principalURI->Equals(mBaseURI, &equal);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  return equal;
+}
 #endif // defined(DEBUG) || !defined(RELEASE_OR_BETA)
 
 bool
 WorkerLoadInfo::ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate)
 {
   nsCOMPtr<nsILoadGroup> nullLoadGroup;
   return ProxyReleaseMainThreadObjects(aWorkerPrivate, nullLoadGroup);
 }
@@ -3864,16 +3915,23 @@ WorkerPrivateParent<Derived>::SetPrincip
 
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA)
 template <class Derived>
 bool
 WorkerPrivateParent<Derived>::FinalChannelPrincipalIsValid(nsIChannel* aChannel)
 {
   return mLoadInfo.FinalChannelPrincipalIsValid(aChannel);
 }
+
+template <class Derived>
+bool
+WorkerPrivateParent<Derived>::PrincipalURIMatchesScriptURL()
+{
+  return mLoadInfo.PrincipalURIMatchesScriptURL();
+}
 #endif
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup)
 {
   AssertIsOnMainThread();
 
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -650,16 +650,19 @@ public:
   SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
 
   nsresult
   SetPrincipalFromChannel(nsIChannel* aChannel);
 
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA)
   bool
   FinalChannelPrincipalIsValid(nsIChannel* aChannel);
+
+  bool
+  PrincipalURIMatchesScriptURL();
 #endif
 
   bool
   UsesSystemPrincipal() const
   {
     return mLoadInfo.mPrincipalIsSystem;
   }
 
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -291,16 +291,19 @@ struct WorkerLoadInfo
   SetPrincipalFromChannel(nsIChannel* aChannel);
 
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA)
   bool
   FinalChannelPrincipalIsValid(nsIChannel* aChannel);
 
   bool
   PrincipalIsValid() const;
+
+  bool
+  PrincipalURIMatchesScriptURL();
 #endif
 
   bool
   ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate);
 
   bool
   ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate,
                                 nsCOMPtr<nsILoadGroup>& aLoadGroupToCancel);