From 890be1ec6dd23f82c3baf080e5f93910e6d80a40 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 10 Mar 2015 11:44:04 -0400 Subject: [PATCH] Bug 1141274 - Allocate shared workers and service workers from separate namespaces; r=nsm This patch makes sure that we never reuse a WorkerPrivate belonging to a shared worker for a service worker and vice versa. --- dom/workers/RuntimeService.cpp | 26 +++++-- dom/workers/test/serviceworkers/mochitest.ini | 2 + .../serviceworker_not_sharedworker.js | 21 ++++++ .../test_serviceworker_not_sharedworker.html | 72 +++++++++++++++++++ 4 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 dom/workers/test/serviceworkers/serviceworker_not_sharedworker.js create mode 100644 dom/workers/test/serviceworkers/test_serviceworker_not_sharedworker.html diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 143d4f56e51..539305d0660 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -265,14 +265,23 @@ GetWorkerPref(const nsACString& aPref, return result; } -// This function creates a key for a SharedWorker composed by "name|scriptSpec". +// This function creates a key for a SharedWorker composed by "shared|name|scriptSpec" +// and a key for a ServiceWorker composed by "service|scope|scriptSpec". // If the name contains a '|', this will be replaced by '||'. void GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName, - nsCString& aKey) + WorkerType aWorkerType, nsCString& aKey) { aKey.Truncate(); - aKey.SetCapacity(aScriptSpec.Length() + aName.Length() + 1); + NS_NAMED_LITERAL_CSTRING(sharedPrefix, "shared|"); + NS_NAMED_LITERAL_CSTRING(servicePrefix, "service|"); + MOZ_ASSERT(servicePrefix.Length() > sharedPrefix.Length()); + MOZ_ASSERT(aWorkerType == WorkerTypeShared || + aWorkerType == WorkerTypeService); + aKey.SetCapacity(servicePrefix.Length() + aScriptSpec.Length() + + aName.Length() + 1); + + aKey.Append(aWorkerType == WorkerTypeService ? servicePrefix : sharedPrefix); nsACString::const_iterator start, end; aName.BeginReading(start); @@ -1463,7 +1472,8 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate) const nsCString& sharedWorkerName = aWorkerPrivate->SharedWorkerName(); nsAutoCString key; - GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName, key); + GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName, + aWorkerPrivate->Type(), key); MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(key)); SharedWorkerInfo* sharedWorkerInfo = @@ -1568,7 +1578,8 @@ RuntimeService::UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate) if (match.mSharedWorkerInfo) { nsAutoCString key; GenerateSharedWorkerKey(match.mSharedWorkerInfo->mScriptSpec, - match.mSharedWorkerInfo->mName, key); + match.mSharedWorkerInfo->mName, + aWorkerPrivate->Type(), key); domainInfo->mSharedWorkerInfos.Remove(key); } } @@ -2297,7 +2308,7 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx, NS_ENSURE_SUCCESS(rv, rv); nsAutoCString key; - GenerateSharedWorkerKey(scriptSpec, aName, key); + GenerateSharedWorkerKey(scriptSpec, aName, aType, key); if (mDomainMap.Get(aLoadInfo->mDomain, &domainInfo) && domainInfo->mSharedWorkerInfos.Get(key, &sharedWorkerInfo)) { @@ -2372,7 +2383,8 @@ RuntimeService::ForgetSharedWorker(WorkerPrivate* aWorkerPrivate) if (match.mSharedWorkerInfo) { nsAutoCString key; GenerateSharedWorkerKey(match.mSharedWorkerInfo->mScriptSpec, - match.mSharedWorkerInfo->mName, key); + match.mSharedWorkerInfo->mName, + aWorkerPrivate->Type(), key); domainInfo->mSharedWorkerInfos.Remove(key); } } diff --git a/dom/workers/test/serviceworkers/mochitest.ini b/dom/workers/test/serviceworkers/mochitest.ini index db54f815fa3..6e5b679f82c 100644 --- a/dom/workers/test/serviceworkers/mochitest.ini +++ b/dom/workers/test/serviceworkers/mochitest.ini @@ -30,6 +30,7 @@ support-files = serviceworker_wrapper.js message_receiver.html close_test.js + serviceworker_not_sharedworker.js [test_unregister.html] [test_installation_simple.html] @@ -46,3 +47,4 @@ support-files = [test_match_all_client_properties.html] [test_close.html] [test_serviceworker_interfaces.html] +[test_serviceworker_not_sharedworker.html] diff --git a/dom/workers/test/serviceworkers/serviceworker_not_sharedworker.js b/dom/workers/test/serviceworkers/serviceworker_not_sharedworker.js new file mode 100644 index 00000000000..077da2366d3 --- /dev/null +++ b/dom/workers/test/serviceworkers/serviceworker_not_sharedworker.js @@ -0,0 +1,21 @@ +function OnMessage(e) +{ + if (e.data.msg == "whoareyou") { + if ("ServiceWorker" in self) { + self.clients.matchAll().then(function(clients) { + clients[0].postMessage({result: "serviceworker"}); + }); + } else { + port.postMessage({result: "sharedworker"}); + } + } +}; + +var port; +onconnect = function(e) { + port = e.ports[0]; + port.onmessage = OnMessage; + port.start(); +}; + +onmessage = OnMessage; diff --git a/dom/workers/test/serviceworkers/test_serviceworker_not_sharedworker.html b/dom/workers/test/serviceworkers/test_serviceworker_not_sharedworker.html new file mode 100644 index 00000000000..5fc433bcbeb --- /dev/null +++ b/dom/workers/test/serviceworkers/test_serviceworker_not_sharedworker.html @@ -0,0 +1,72 @@ + + + + + Bug 1141274 - test that service workers and shared workers are separate + + + + +

+ +

+
+
+
+