summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornhiroki@chromium.org <nhiroki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-17 12:15:33 +0000
committernhiroki@chromium.org <nhiroki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-17 12:15:33 +0000
commitc5e16594abd7f84007bfadbb23560c1f4b6b9f19 (patch)
tree4609bafcc05a4fdaf838f8cbf5f0bc542bc10507
parent8c7ca16d4b760b98f46b4689e65fe4b251c54532 (diff)
downloadchromium_src-c5e16594abd7f84007bfadbb23560c1f4b6b9f19.zip
chromium_src-c5e16594abd7f84007bfadbb23560c1f4b6b9f19.tar.gz
chromium_src-c5e16594abd7f84007bfadbb23560c1f4b6b9f19.tar.bz2
ServiceWorker: Confirm the liveness of the associated context before handling message
SWProviderHost is associated with SWContextCore which can be purged on corruption recovery process while the host is still referring to it, so the host should check the liveness of the context before handling the message from renderer. BUG=371675 TEST=content_unittests Review URL: https://codereview.chromium.org/325173002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277738 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.cc25
-rw-r--r--content/browser/service_worker/service_worker_provider_host.cc4
-rw-r--r--content/browser/service_worker/service_worker_provider_host.h4
-rw-r--r--content/browser/service_worker/service_worker_register_job.cc4
-rw-r--r--content/browser/service_worker/service_worker_request_handler.cc2
5 files changed, 37 insertions, 2 deletions
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 8cacc34..7e216d2 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -179,6 +179,14 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
BadMessageReceived();
return;
}
+ if (!provider_host->IsContextAlive()) {
+ Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
+ thread_id,
+ request_id,
+ WebServiceWorkerError::ErrorTypeDisabled,
+ base::ASCIIToUTF16(kDisabledErrorMessage)));
+ return;
+ }
GetContext()->RegisterServiceWorker(
pattern,
@@ -214,6 +222,14 @@ void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
BadMessageReceived();
return;
}
+ if (!provider_host->IsContextAlive()) {
+ Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
+ thread_id,
+ request_id,
+ blink::WebServiceWorkerError::ErrorTypeDisabled,
+ base::ASCIIToUTF16(kDisabledErrorMessage)));
+ return;
+ }
GetContext()->UnregisterServiceWorker(
pattern,
@@ -275,10 +291,14 @@ void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
return;
ServiceWorkerProviderHost* provider_host =
GetContext()->GetProviderHost(render_process_id_, provider_id);
- if (!provider_host || !provider_host->SetHostedVersionId(version_id)) {
+ if (!provider_host) {
BadMessageReceived();
return;
}
+ if (!provider_host->IsContextAlive())
+ return;
+ if (!provider_host->SetHostedVersionId(version_id))
+ BadMessageReceived();
}
void ServiceWorkerDispatcherHost::RegistrationComplete(
@@ -306,6 +326,9 @@ void ServiceWorkerDispatcherHost::RegistrationComplete(
RegisterServiceWorkerHandle(handle.Pass());
}
+// TODO(nhiroki): These message handlers that take |embedded_worker_id| as an
+// input should check if the worker refers to the live context. If the context
+// was deleted, handle the messege gracefully (http://crbug.com/371675).
void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(int embedded_worker_id) {
if (!GetContext())
return;
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index a41085c..eeba3736 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -173,4 +173,8 @@ ServiceWorkerObjectInfo ServiceWorkerProviderHost::CreateHandleAndPass(
return info;
}
+bool ServiceWorkerProviderHost::IsContextAlive() {
+ return context_ != NULL;
+}
+
} // namespace content
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index d6f1ec8..31f4a37 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -94,6 +94,10 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// versions.
bool ValidateVersionForAssociation(ServiceWorkerVersion* version);
+ // Returns true if the context referred to by this host (i.e. |context_|) is
+ // still alive.
+ bool IsContextAlive();
+
// Dispatches message event to the document.
void PostMessage(const base::string16& message,
const std::vector<int>& sent_message_port_ids);
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index 5948dcf..6eba2e8 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -412,6 +412,8 @@ void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments(
!it->IsAtEnd();
it->Advance()) {
ServiceWorkerProviderHost* host = it->GetProviderHost();
+ if (!host->IsContextAlive())
+ continue;
if (ServiceWorkerUtils::ScopeMatches(version->scope(),
host->document_url())) {
// The spec's _Update algorithm says, "upgrades active version to a new
@@ -440,6 +442,8 @@ void ServiceWorkerRegisterJob::DisassociateWaitingVersionFromDocuments(
!it->IsAtEnd();
it->Advance()) {
ServiceWorkerProviderHost* host = it->GetProviderHost();
+ if (!host->IsContextAlive())
+ continue;
if (host->waiting_version() &&
host->waiting_version()->version_id() == version_id) {
host->SetWaitingVersion(NULL);
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc
index 3faf502..a04e0116 100644
--- a/content/browser/service_worker/service_worker_request_handler.cc
+++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -70,7 +70,7 @@ void ServiceWorkerRequestHandler::InitializeHandler(
ServiceWorkerProviderHost* provider_host =
context_wrapper->context()->GetProviderHost(process_id, provider_id);
- if (!provider_host)
+ if (!provider_host || !provider_host->IsContextAlive())
return;
scoped_ptr<ServiceWorkerRequestHandler> handler(