Bug 1173467 P3 Pass private browsing flag into CacheStorage factory methods. r=ehsan
authorBen Kelly <ben@wanderview.com>
Fri, 26 Jun 2015 19:36:40 -0700
changeset 281259 515147dbf45582045cb7d36f99866548b8a5dbd6
parent 281258 3d9ba1e0e23e5ef68aabf282a7b1e8c6a67a7339
child 281260 ac30d7919319b83cdcd42308baf911222b2c95a8
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1173467
milestone41.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 1173467 P3 Pass private browsing flag into CacheStorage factory methods. r=ehsan
dom/base/nsGlobalWindow.cpp
dom/cache/CacheStorage.cpp
dom/cache/CacheStorage.h
dom/workers/ScriptLoader.cpp
dom/workers/ServiceWorkerScriptCache.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10491,17 +10491,18 @@ nsGlobalWindow::GetInterface(JSContext* 
   dom::GetInterface(aCx, this, aIID, aRetval, aError);
 }
 
 already_AddRefed<CacheStorage>
 nsGlobalWindow::GetCaches(ErrorResult& aRv)
 {
   if (!mCacheStorage) {
     mCacheStorage = CacheStorage::CreateOnMainThread(cache::DEFAULT_NAMESPACE,
-                                                     this, GetPrincipal(), aRv);
+                                                     this, GetPrincipal(),
+                                                     IsPrivateBrowsing(), aRv);
   }
 
   nsRefPtr<CacheStorage> ref = mCacheStorage;
   return ref.forget();
 }
 
 void
 nsGlobalWindow::FireOfflineStatusEventIfChanged()
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/dom/cache/Feature.h"
 #include "mozilla/dom/cache/PCacheChild.h"
 #include "mozilla/dom/cache/ReadStream.h"
 #include "mozilla/dom/cache/TypeUtils.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "nsIDocument.h"
 #include "nsIGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "WorkerPrivate.h"
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
@@ -59,22 +60,28 @@ struct CacheStorage::Entry final
   // We cannot add the requests until after the actor is present.  So store
   // the request data separately for now.
   nsRefPtr<InternalRequest> mRequest;
 };
 
 // static
 already_AddRefed<CacheStorage>
 CacheStorage::CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
-                                 nsIPrincipal* aPrincipal, ErrorResult& aRv)
+                                 nsIPrincipal* aPrincipal, bool aPrivateBrowsing,
+                                 ErrorResult& aRv)
 {
   MOZ_ASSERT(aGlobal);
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(NS_IsMainThread());
 
+  if (aPrivateBrowsing) {
+    NS_WARNING("CacheStorage not supported during private browsing.");
+    nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
+  }
 
   bool nullPrincipal;
   nsresult rv = aPrincipal->GetIsNullPrincipal(&nullPrincipal);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
     return nullptr;
   }
 
@@ -112,16 +119,22 @@ CacheStorage::CreateOnMainThread(Namespa
 already_AddRefed<CacheStorage>
 CacheStorage::CreateOnWorker(Namespace aNamespace, nsIGlobalObject* aGlobal,
                              WorkerPrivate* aWorkerPrivate, ErrorResult& aRv)
 {
   MOZ_ASSERT(aGlobal);
   MOZ_ASSERT(aWorkerPrivate);
   aWorkerPrivate->AssertIsOnWorkerThread();
 
+  if (aWorkerPrivate->IsInPrivateBrowsing()) {
+    NS_WARNING("CacheStorage not supported during private browsing.");
+    nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
+  }
+
   nsRefPtr<Feature> feature = Feature::Create(aWorkerPrivate);
   if (!feature) {
     NS_WARNING("Worker thread is shutting down.");
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   const PrincipalInfo& principalInfo = aWorkerPrivate->GetPrincipalInfo();
@@ -339,17 +352,28 @@ CacheStorage::Constructor(const GlobalOb
                 "Default namespace should match webidl Content enum");
   static_assert(CHROME_ONLY_NAMESPACE == (uint32_t)CacheStorageNamespace::Chrome,
                 "Chrome namespace should match webidl Chrome enum");
   static_assert(NUMBER_OF_NAMESPACES == (uint32_t)CacheStorageNamespace::EndGuard_,
                 "Number of namespace should match webidl endguard enum");
 
   Namespace ns = static_cast<Namespace>(aNamespace);
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  return CreateOnMainThread(ns, global, aPrincipal, aRv);
+
+  bool privateBrowsing = false;
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global);
+  if (window) {
+    nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
+    if (doc) {
+      nsCOMPtr<nsILoadContext> loadContext = doc->GetLoadContext();
+      privateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
+    }
+  }
+
+  return CreateOnMainThread(ns, global, aPrincipal, privateBrowsing, aRv);
 }
 
 nsISupports*
 CacheStorage::GetParentObject() const
 {
   return mGlobal;
 }
 
--- a/dom/cache/CacheStorage.h
+++ b/dom/cache/CacheStorage.h
@@ -44,17 +44,18 @@ class CacheStorage final : public nsIIPC
                          , public nsWrapperCache
                          , public TypeUtils
 {
   typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
 
 public:
   static already_AddRefed<CacheStorage>
   CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
-                     nsIPrincipal* aPrincipal, ErrorResult& aRv);
+                     nsIPrincipal* aPrincipal, bool aPrivateBrowsing,
+                     ErrorResult& aRv);
 
   static already_AddRefed<CacheStorage>
   CreateOnWorker(Namespace aNamespace, nsIGlobalObject* aGlobal,
                  workers::WorkerPrivate* aWorkerPrivate, ErrorResult& aRv);
 
   // webidl interface methods
   already_AddRefed<Promise> Match(const RequestOrUSVString& aRequest,
                                   const CacheQueryOptions& aOptions,
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -317,16 +317,17 @@ private:
 
 class CacheScriptLoader;
 
 class CacheCreator final : public PromiseNativeHandler
 {
 public:
   explicit CacheCreator(WorkerPrivate* aWorkerPrivate)
     : mCacheName(aWorkerPrivate->ServiceWorkerCacheName())
+    , mPrivateBrowsing(aWorkerPrivate->IsInPrivateBrowsing())
   {
     MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
     MOZ_ASSERT(aWorkerPrivate->LoadScriptAsPartOfLoadingServiceWorkerScript());
     AssertIsOnMainThread();
   }
 
   void
   AddLoader(CacheScriptLoader* aLoader)
@@ -377,16 +378,17 @@ private:
   FailLoaders(nsresult aRv);
 
   nsRefPtr<Cache> mCache;
   nsRefPtr<CacheStorage> mCacheStorage;
   nsCOMPtr<nsIGlobalObject> mSandboxGlobalObject;
   nsTArray<nsRefPtr<CacheScriptLoader>> mLoaders;
 
   nsString mCacheName;
+  bool mPrivateBrowsing;
 };
 
 class CacheScriptLoader final : public PromiseNativeHandler
                                   , public nsIStreamLoaderObserver
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSISTREAMLOADEROBSERVER
@@ -1236,21 +1238,29 @@ CacheCreator::CreateCacheStorage(nsIPrin
     return rv;
   }
 
   mSandboxGlobalObject = xpc::NativeGlobal(sandbox->GetJSObject());
   if (NS_WARN_IF(!mSandboxGlobalObject)) {
     return NS_ERROR_FAILURE;
   }
 
+  // If we're in private browsing mode, don't even try to create the
+  // CacheStorage.  Instead, just fail immediately to terminate the
+  // ServiceWorker load.
+  if (NS_WARN_IF(mPrivateBrowsing)) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
   ErrorResult error;
   mCacheStorage =
     CacheStorage::CreateOnMainThread(cache::CHROME_ONLY_NAMESPACE,
                                      mSandboxGlobalObject,
-                                     aPrincipal, error);
+                                     aPrincipal, mPrivateBrowsing,
+                                     error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   return NS_OK;
 }
 
 nsresult
--- a/dom/workers/ServiceWorkerScriptCache.cpp
+++ b/dom/workers/ServiceWorkerScriptCache.cpp
@@ -49,19 +49,24 @@ CreateCacheStorage(nsIPrincipal* aPrinci
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   if (aHolder) {
     sandbox.forget(aHolder);
   }
 
+  // We assume private browsing is not enabled here.  The ScriptLoader
+  // explicitly fails for private browsing so there should never be
+  // a service worker running in private browsing mode.  Therefore if
+  // we are purging scripts or running a comparison algorithm we cannot
+  // be in private browing.
   return CacheStorage::CreateOnMainThread(cache::CHROME_ONLY_NAMESPACE,
-                                          sandboxGlobalObject,
-                                          aPrincipal, aRv);
+                                          sandboxGlobalObject, aPrincipal,
+                                          false /* private browsing */, aRv);
 }
 
 class CompareManager;
 
 // This class downloads a URL from the network and then it calls
 // NetworkFinished() in the CompareManager.
 class CompareNetwork final : public nsIStreamLoaderObserver,
                              public nsIRequestObserver