Commit f16727ab authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

service worker: Check weak ptr for null in StartRequestWithCustomTimeout.

context_ may be null. It's not easy to cleanly abort in this case since
the function returns a value. Since context_ is just used for some
bookkeeping, just skip that when it's null.

Bug: 877350
Change-Id: I696d08999fe6aa861be206381a4c162e3faa4758
Reviewed-on: https://chromium-review.googlesource.com/1188002Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585771}
parent 03168d86
......@@ -520,25 +520,29 @@ int ServiceWorkerVersion::StartRequestWithCustomTimeout(
<< "Event of type " << static_cast<int>(event_type)
<< " can only be dispatched to an active worker: " << status();
if (context_ &&
event_type == ServiceWorkerMetrics::EventType::LONG_RUNNING_MESSAGE) {
context_->embedded_worker_registry()->AbortLifetimeTracking(
embedded_worker_->embedded_worker_id());
}
if (event_type != ServiceWorkerMetrics::EventType::INSTALL &&
event_type != ServiceWorkerMetrics::EventType::ACTIVATE &&
event_type != ServiceWorkerMetrics::EventType::MESSAGE) {
// Reset the self-update delay iff this is not an event that can triggered
// by a service worker itself. Otherwise, service workers can use update()
// to keep running forever via install and activate events, or postMessage()
// between themselves to reset the delay via message event.
// postMessage() resets the delay in ServiceWorkerObjectHost, iff it didn't
// come from a service worker.
ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(registration_id_);
DCHECK(registration) << "running workers should have a live registration";
registration->set_self_update_delay(base::TimeDelta());
// |context_| is needed for some bookkeeping. If there's no context, the
// request will be aborted soon, so don't bother aborting the request directly
// here, and just skip this bookkeeping.
if (context_) {
if (event_type == ServiceWorkerMetrics::EventType::LONG_RUNNING_MESSAGE) {
context_->embedded_worker_registry()->AbortLifetimeTracking(
embedded_worker_->embedded_worker_id());
}
if (event_type != ServiceWorkerMetrics::EventType::INSTALL &&
event_type != ServiceWorkerMetrics::EventType::ACTIVATE &&
event_type != ServiceWorkerMetrics::EventType::MESSAGE) {
// Reset the self-update delay iff this is not an event that can triggered
// by a service worker itself. Otherwise, service workers can use update()
// to keep running forever via install and activate events, or
// postMessage() between themselves to reset the delay via message event.
// postMessage() resets the delay in ServiceWorkerObjectHost, iff it
// didn't come from a service worker.
ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(registration_id_);
DCHECK(registration) << "running workers should have a live registration";
registration->set_self_update_delay(base::TimeDelta());
}
}
auto request = std::make_unique<InflightRequest>(
......
......@@ -94,6 +94,7 @@ FORWARD_DECLARE_TEST(ServiceWorkerVersionTest, StaleUpdate_FreshWorker);
FORWARD_DECLARE_TEST(ServiceWorkerVersionTest, StaleUpdate_NonActiveWorker);
FORWARD_DECLARE_TEST(ServiceWorkerVersionTest, StaleUpdate_RunningWorker);
FORWARD_DECLARE_TEST(ServiceWorkerVersionTest, StaleUpdate_StartWorker);
FORWARD_DECLARE_TEST(ServiceWorkerVersionTest, StartRequestWithNullContext);
} // namespace service_worker_version_unittest
namespace service_worker_registration_unittest {
......@@ -551,6 +552,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
FRIEND_TEST_ALL_PREFIXES(
service_worker_version_unittest::ServiceWorkerVersionTest,
StaleUpdate_DoNotDeferTimer);
FRIEND_TEST_ALL_PREFIXES(
service_worker_version_unittest::ServiceWorkerVersionTest,
StartRequestWithNullContext);
FRIEND_TEST_ALL_PREFIXES(
service_worker_version_unittest::ServiceWorkerRequestTimeoutTest,
RequestTimeout);
......
......@@ -773,6 +773,15 @@ TEST_F(ServiceWorkerVersionTest, StaleUpdate_DoNotDeferTimer) {
EXPECT_EQ(run_time, version_->update_timer_.desired_run_time());
}
TEST_F(ServiceWorkerVersionTest, StartRequestWithNullContext) {
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
version_->context_ = nullptr;
version_->StartRequest(ServiceWorkerMetrics::EventType::PUSH,
base::DoNothing());
// Test passes if it doesn't crash.
}
// Tests the delay mechanism for self-updating service workers, to prevent
// them from running forever (see https://crbug.com/805496).
TEST_F(ServiceWorkerVersionTest, ResetUpdateDelay) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment