a9f81e63c4
* chore: [31-x-y] cherry-pick 3 changes from 0-M127 * 44b7fbf35b10 from chromium * c9815acd5a88 from dawn * 9463ce9cd8d9 from DirectXShaderCompiler * chore: e patches all --------- Co-authored-by: Charles Kerr <charles@charleskerr.com>
288 lines
11 KiB
Diff
288 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Hiroshige Hayashizaki <hiroshige@chromium.org>
|
|
Date: Tue, 16 Jul 2024 03:44:29 +0000
|
|
Subject: Handle ThrottlingURLLoader deletion during throttle calls
|
|
|
|
Theoretically `ThrottlingURLLoader` can be deleted during
|
|
throttle calls and some call sites have already protection
|
|
for such cases. This CL adds the protection for more call sites.
|
|
|
|
This CL also adds more unit tests for cancelling/deleting
|
|
`ThrottlingURLLoader` during throttle calls.
|
|
|
|
(cherry picked from commit c40f8866cfd6438725cc58e5db2d792e6d9f869b)
|
|
|
|
Bug: 349342289
|
|
Change-Id: I80d64be9ba1a3ac920315f5b4012b29c9737e414
|
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5665925
|
|
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
|
|
Reviewed-by: Tsuyoshi Horo <horo@chromium.org>
|
|
Cr-Original-Commit-Position: refs/heads/main@{#1323986}
|
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5710951
|
|
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
|
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
|
|
Cr-Commit-Position: refs/branch-heads/6533@{#1515}
|
|
Cr-Branched-From: 7e0b87ec6b8cb5cb2969e1479fc25776e582721d-refs/heads/main@{#1313161}
|
|
|
|
diff --git a/third_party/blink/common/loader/throttling_url_loader.cc b/third_party/blink/common/loader/throttling_url_loader.cc
|
|
index b4924e7441f45881ad1e33aaab61a49400832f54..eeed93d8e7791b51bf17b4b6243251823824872b 100644
|
|
--- a/third_party/blink/common/loader/throttling_url_loader.cc
|
|
+++ b/third_party/blink/common/loader/throttling_url_loader.cc
|
|
@@ -660,8 +660,12 @@ void ThrottlingURLLoader::OnReceiveResponse(
|
|
for (auto& entry : throttles_) {
|
|
auto* throttle = entry.throttle.get();
|
|
base::Time start = base::Time::Now();
|
|
+ auto weak_ptr = weak_factory_.GetWeakPtr();
|
|
throttle->BeforeWillProcessResponse(response_url_, *response_head,
|
|
&has_pending_restart);
|
|
+ if (!weak_ptr) {
|
|
+ return;
|
|
+ }
|
|
RecordExecutionTimeHistogram("BeforeWillProcessResponse", start);
|
|
if (!HandleThrottleResult(throttle)) {
|
|
return;
|
|
@@ -681,8 +685,12 @@ void ThrottlingURLLoader::OnReceiveResponse(
|
|
auto* throttle = entry.throttle.get();
|
|
bool throttle_deferred = false;
|
|
base::Time start = base::Time::Now();
|
|
+ auto weak_ptr = weak_factory_.GetWeakPtr();
|
|
throttle->WillProcessResponse(response_url_, response_head.get(),
|
|
&throttle_deferred);
|
|
+ if (!weak_ptr) {
|
|
+ return;
|
|
+ }
|
|
RecordExecutionTimeHistogram(GetStageNameForHistogram(DEFERRED_RESPONSE),
|
|
start);
|
|
if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
|
|
@@ -852,7 +860,11 @@ void ThrottlingURLLoader::OnComplete(
|
|
for (auto& entry : throttles_) {
|
|
auto* throttle = entry.throttle.get();
|
|
base::Time start = base::Time::Now();
|
|
+ auto weak_ptr = weak_factory_.GetWeakPtr();
|
|
throttle->WillOnCompleteWithError(status);
|
|
+ if (!weak_ptr) {
|
|
+ return;
|
|
+ }
|
|
RecordExecutionTimeHistogram("WillOnCompleteWithError", start);
|
|
if (!HandleThrottleResult(throttle)) {
|
|
return;
|
|
diff --git a/third_party/blink/common/loader/throttling_url_loader_unittest.cc b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
|
|
index 2c73705d12445c13067e937b4bfae1c99290da09..a7e037b2dde9390d9cc15d863ed926809f9afccf 100644
|
|
--- a/third_party/blink/common/loader/throttling_url_loader_unittest.cc
|
|
+++ b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
|
|
@@ -338,9 +338,9 @@ class TestURLLoaderThrottle : public blink::URLLoaderThrottle {
|
|
network::mojom::URLResponseHead* response_head,
|
|
bool* defer) override {
|
|
will_process_response_called_++;
|
|
+ response_url_ = response_url;
|
|
if (will_process_response_callback_)
|
|
will_process_response_callback_.Run(delegate_.get(), defer);
|
|
- response_url_ = response_url;
|
|
}
|
|
|
|
void BeforeWillProcessResponse(
|
|
@@ -422,6 +422,11 @@ class ThrottlingURLLoaderTest : public testing::Test {
|
|
factory_.factory_remote().FlushForTesting();
|
|
}
|
|
|
|
+ void ResetLoader() {
|
|
+ ResetThrottleRawPointer();
|
|
+ loader_.reset();
|
|
+ }
|
|
+
|
|
void ResetThrottleRawPointer() { throttle_ = nullptr; }
|
|
|
|
// Be the first member so it is destroyed last.
|
|
@@ -467,6 +472,25 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeStart) {
|
|
EXPECT_EQ(1u, client_.on_complete_called());
|
|
}
|
|
|
|
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeStart) {
|
|
+ base::RunLoop run_loop;
|
|
+ throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
|
|
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
|
|
+ bool* defer) {
|
|
+ ResetLoader();
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(1u, factory_.create_loader_and_start_called());
|
|
+
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(0u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
TEST_F(ThrottlingURLLoaderTest, DeferBeforeStart) {
|
|
throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
|
|
[](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
|
|
@@ -667,6 +691,88 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeRedirect) {
|
|
EXPECT_EQ(1u, client_.on_complete_called());
|
|
}
|
|
|
|
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeRedirect) {
|
|
+ base::RunLoop run_loop;
|
|
+ throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
|
|
+ [this, &run_loop](
|
|
+ blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
|
|
+ std::vector<std::string>* /* removed_headers */,
|
|
+ net::HttpRequestHeaders* /* modified_headers */,
|
|
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
|
|
+ ResetLoader();
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+
|
|
+ factory_.NotifyClientOnReceiveRedirect();
|
|
+
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(0u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillRedirect) {
|
|
+ throttle_->set_before_will_redirect_request_callback(
|
|
+ base::BindLambdaForTesting(
|
|
+ [](blink::URLLoaderThrottle::Delegate* delegate,
|
|
+ RestartWithURLReset* restart_with_url_reset,
|
|
+ std::vector<std::string>* /* removed_headers */,
|
|
+ net::HttpRequestHeaders* /* modified_headers */,
|
|
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
|
|
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
|
|
+ }));
|
|
+
|
|
+ base::RunLoop run_loop;
|
|
+ client_.set_on_complete_callback(
|
|
+ base::BindLambdaForTesting([&run_loop](int error) {
|
|
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+
|
|
+ factory_.NotifyClientOnReceiveRedirect();
|
|
+
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
|
|
+ EXPECT_EQ(1u, throttle_->will_redirect_request_called());
|
|
+ EXPECT_EQ(0u, throttle_->before_will_process_response_called());
|
|
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
|
|
+
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(1u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillRedirect) {
|
|
+ base::RunLoop run_loop;
|
|
+ throttle_->set_before_will_redirect_request_callback(
|
|
+ base::BindLambdaForTesting(
|
|
+ [this, &run_loop](
|
|
+ blink::URLLoaderThrottle::Delegate* delegate,
|
|
+ RestartWithURLReset* restart_with_url_reset,
|
|
+ std::vector<std::string>* /* removed_headers */,
|
|
+ net::HttpRequestHeaders* /* modified_headers */,
|
|
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
|
|
+ ResetLoader();
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+
|
|
+ factory_.NotifyClientOnReceiveRedirect();
|
|
+
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(0u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
TEST_F(ThrottlingURLLoaderTest, DeferBeforeRedirect) {
|
|
base::RunLoop run_loop1;
|
|
throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
|
|
@@ -880,6 +986,77 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) {
|
|
EXPECT_EQ(1u, client_.on_complete_called());
|
|
}
|
|
|
|
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeResponse) {
|
|
+ base::RunLoop run_loop;
|
|
+ throttle_->set_will_process_response_callback(base::BindLambdaForTesting(
|
|
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
|
|
+ bool* defer) {
|
|
+ ResetLoader();
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+
|
|
+ factory_.NotifyClientOnReceiveResponse();
|
|
+
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(0u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillProcessResponse) {
|
|
+ throttle_->set_before_will_process_response_callback(
|
|
+ base::BindLambdaForTesting(
|
|
+ [](blink::URLLoaderThrottle::Delegate* delegate,
|
|
+ RestartWithURLReset* restart_with_url_reset) {
|
|
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
|
|
+ }));
|
|
+
|
|
+ base::RunLoop run_loop;
|
|
+ client_.set_on_complete_callback(
|
|
+ base::BindLambdaForTesting([&run_loop](int error) {
|
|
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+
|
|
+ factory_.NotifyClientOnReceiveResponse();
|
|
+
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
|
|
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
|
|
+ EXPECT_EQ(1u, throttle_->before_will_process_response_called());
|
|
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(1u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillProcessResponse) {
|
|
+ base::RunLoop run_loop;
|
|
+ throttle_->set_before_will_process_response_callback(
|
|
+ base::BindLambdaForTesting(
|
|
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
|
|
+ RestartWithURLReset* restart_with_url_reset) {
|
|
+ ResetLoader();
|
|
+ run_loop.Quit();
|
|
+ }));
|
|
+
|
|
+ CreateLoaderAndStart();
|
|
+
|
|
+ factory_.NotifyClientOnReceiveResponse();
|
|
+
|
|
+ run_loop.Run();
|
|
+
|
|
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
|
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
|
+ EXPECT_EQ(0u, client_.on_complete_called());
|
|
+}
|
|
+
|
|
TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
|
|
base::RunLoop run_loop1;
|
|
throttle_->set_will_process_response_callback(base::BindRepeating(
|