diff options
author | nhiroki@chromium.org <nhiroki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 12:15:33 +0000 |
---|---|---|
committer | nhiroki@chromium.org <nhiroki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 12:15:33 +0000 |
commit | c5e16594abd7f84007bfadbb23560c1f4b6b9f19 (patch) | |
tree | 4609bafcc05a4fdaf838f8cbf5f0bc542bc10507 | |
parent | 8c7ca16d4b760b98f46b4689e65fe4b251c54532 (diff) | |
download | chromium_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
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( |