Bug 1343308 P1 Make Clients.matchAll() only return Clients controlled by the current service worker. r=baku
authorBen Kelly <ben@wanderview.com>
Wed, 01 Mar 2017 13:08:54 -0500
changeset 491171 1a34bdb0c31a69914719d5b68e05781e4e62b81c
parent 491170 eb6b998cfa79ea7eddbba71ccb3e9c8e327691aa
child 491172 b8a79ad3b03e21a21477d1d03311e623e277680d
push id47336
push userbmo:eoger@fastmail.com
push dateWed, 01 Mar 2017 21:01:30 +0000
reviewersbaku
bugs1343308
milestone54.0a1
Bug 1343308 P1 Make Clients.matchAll() only return Clients controlled by the current service worker. r=baku
dom/workers/ServiceWorkerClients.cpp
dom/workers/ServiceWorkerManager.cpp
dom/workers/ServiceWorkerManager.h
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -188,24 +188,27 @@ class MatchAllRunnable final : public Ru
 
       promise->MaybeResolve(ret);
       mPromiseProxy->CleanUp();
       return true;
     }
   };
 
   RefPtr<PromiseWorkerProxy> mPromiseProxy;
-  nsCString mScope;
-  bool mIncludeUncontrolled;
+  const nsCString mScope;
+  const uint64_t mServiceWorkerID;
+  const bool mIncludeUncontrolled;
 public:
   MatchAllRunnable(PromiseWorkerProxy* aPromiseProxy,
                    const nsCString& aScope,
+                   uint64_t aServiceWorkerID,
                    bool aIncludeUncontrolled)
     : mPromiseProxy(aPromiseProxy),
       mScope(aScope),
+      mServiceWorkerID(aServiceWorkerID),
       mIncludeUncontrolled(aIncludeUncontrolled)
   {
     MOZ_ASSERT(mPromiseProxy);
   }
 
   NS_IMETHOD
   Run() override
   {
@@ -215,17 +218,18 @@ public:
     if (mPromiseProxy->CleanedUp()) {
       return NS_OK;
     }
 
     nsTArray<ServiceWorkerClientInfo> result;
     RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     if (swm) {
       swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(),
-                         mScope, mIncludeUncontrolled, result);
+                         mScope, mServiceWorkerID, mIncludeUncontrolled,
+                         result);
     }
     RefPtr<ResolvePromiseWorkerRunnable> r =
       new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
                                        mPromiseProxy, result);
 
     r->Dispatch();
     return NS_OK;
   }
@@ -826,16 +830,17 @@ ServiceWorkerClients::MatchAll(const Cli
   if (!promiseProxy) {
     promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     return promise.forget();
   }
 
   RefPtr<MatchAllRunnable> r =
     new MatchAllRunnable(promiseProxy,
                          NS_ConvertUTF16toUTF8(scope),
+                         workerPrivate->ServiceWorkerID(),
                          aOptions.mIncludeUncontrolled);
   MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
   return promise.forget();
 }
 
 already_AddRefed<Promise>
 ServiceWorkerClients::OpenWindow(const nsAString& aUrl,
                                  ErrorResult& aRv)
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -2944,16 +2944,17 @@ ServiceWorkerManager::GetClient(nsIPrinc
 
   clientInfo.reset(new ServiceWorkerClientInfo(doc));
   return clientInfo;
 }
 
 void
 ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
                                     const nsCString& aScope,
+                                    uint64_t aServiceWorkerID,
                                     bool aIncludeUncontrolled,
                                     nsTArray<ServiceWorkerClientInfo>& aDocuments)
 {
   MOZ_ASSERT(aPrincipal);
 
   RefPtr<ServiceWorkerRegistrationInfo> registration =
     GetRegistration(aPrincipal, aScope);
 
@@ -2999,20 +3000,23 @@ ServiceWorkerManager::GetAllClients(nsIP
     // setting is enabled.
     if (!doc->GetWindow()->GetServiceWorkersTestingEnabled() &&
         !Preferences::GetBool("dom.serviceWorkers.testing.enabled") &&
         !IsFromAuthenticatedOrigin(doc)) {
       continue;
     }
 
     // If we are only returning controlled Clients then skip any documents
-    // that are for different registrations.
+    // that are for different registrations.  We also skip service workers
+    // that don't match the ID of our calling service worker.  We should
+    // only return Clients controlled by that precise service worker.
     if (!aIncludeUncontrolled) {
       ServiceWorkerRegistrationInfo* reg = mControlledDocuments.GetWeak(doc);
-      if (!reg || reg->mScope != registration->mScope) {
+      if (!reg || reg->mScope != aScope || !reg->GetActive() ||
+          reg->GetActive()->ID() != aServiceWorkerID) {
         continue;
       }
     }
 
     if (!aIncludeUncontrolled && !mControlledDocuments.Contains(doc)) {
       continue;
     }
 
--- a/dom/workers/ServiceWorkerManager.h
+++ b/dom/workers/ServiceWorkerManager.h
@@ -267,16 +267,17 @@ public:
   UniquePtr<ServiceWorkerClientInfo>
   GetClient(nsIPrincipal* aPrincipal,
             const nsAString& aClientId,
             ErrorResult& aRv);
 
   void
   GetAllClients(nsIPrincipal* aPrincipal,
                 const nsCString& aScope,
+                uint64_t aServiceWorkerID,
                 bool aIncludeUncontrolled,
                 nsTArray<ServiceWorkerClientInfo>& aDocuments);
 
   void
   MaybeClaimClient(nsIDocument* aDocument,
                    ServiceWorkerRegistrationInfo* aWorkerRegistration);
 
   nsresult