Skip to content

Commit 2955468

Browse files
committed
Don't access ThrottlingURLLoader after calls to |forwarding_client_|
The contract for |forwarding_client_| is that the implementation is free to delete the loader synchronously after calling any of its methods. There is one case where we reach into |this| after doing so, which this CL fixes. Bug: 833292 Change-Id: Ic5e41649da9e692407f0433a72d2d784f174497b Reviewed-on: https://chromium-review.googlesource.com/1014024 Commit-Queue: Charlie Harrison <csharrison@chromium.org> Reviewed-by: John Abd-El-Malek <jam@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#550998}(cherry picked from commit 5adb577) Reviewed-on: https://chromium-review.googlesource.com/1015722 Reviewed-by: Charlie Harrison <csharrison@chromium.org> Cr-Commit-Position: refs/branch-heads/3396@{#65} Cr-Branched-From: 9ef2aa8-refs/heads/master@{#550428}
1 parent e9e023a commit 2955468

2 files changed

Lines changed: 66 additions & 5 deletions

File tree

content/common/throttling_url_loader.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,19 +465,21 @@ void ThrottlingURLLoader::Resume() {
465465
}
466466
case DEFERRED_REDIRECT: {
467467
client_binding_.ResumeIncomingMethodCallProcessing();
468-
forwarding_client_->OnReceiveRedirect(redirect_info_->redirect_info,
469-
redirect_info_->response_head);
470468
// TODO(dhausknecht) at this point we do not actually know if we commit to
471469
// the redirect or if it will be cancelled. FollowRedirect would be a more
472470
// suitable place to set this URL but there we do not have the data.
473471
response_url_ = redirect_info_->redirect_info.new_url;
472+
forwarding_client_->OnReceiveRedirect(redirect_info_->redirect_info,
473+
redirect_info_->response_head);
474+
// Note: |this| may be deleted here.
474475
break;
475476
}
476477
case DEFERRED_RESPONSE: {
477478
client_binding_.ResumeIncomingMethodCallProcessing();
478479
forwarding_client_->OnReceiveResponse(
479480
response_info_->response_head,
480481
std::move(response_info_->downloaded_file));
482+
// Note: |this| may be deleted here.
481483
break;
482484
}
483485
default:

content/common/throttling_url_loader_unittest.cc

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,13 @@ class TestURLLoaderClient : public network::mojom::URLLoaderClient {
134134

135135
size_t on_complete_called() const { return on_complete_called_; }
136136

137-
void set_on_received_response_callback(const base::Closure& callback) {
137+
void set_on_received_redirect_callback(
138+
const base::RepeatingClosure& callback) {
139+
on_received_redirect_callback_ = callback;
140+
}
141+
142+
void set_on_received_response_callback(
143+
const base::RepeatingClosure& callback) {
138144
on_received_response_callback_ = callback;
139145
}
140146

@@ -156,6 +162,8 @@ class TestURLLoaderClient : public network::mojom::URLLoaderClient {
156162
const net::RedirectInfo& redirect_info,
157163
const network::ResourceResponseHead& response_head) override {
158164
on_received_redirect_called_++;
165+
if (on_received_redirect_callback_)
166+
on_received_redirect_callback_.Run();
159167
}
160168
void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override {}
161169
void OnUploadProgress(int64_t current_position,
@@ -175,7 +183,8 @@ class TestURLLoaderClient : public network::mojom::URLLoaderClient {
175183
size_t on_received_redirect_called_ = 0;
176184
size_t on_complete_called_ = 0;
177185

178-
base::Closure on_received_response_callback_;
186+
base::RepeatingClosure on_received_redirect_callback_;
187+
base::RepeatingClosure on_received_response_callback_;
179188
OnCompleteCallback on_complete_callback_;
180189

181190
DISALLOW_COPY_AND_ASSIGN(TestURLLoaderClient);
@@ -904,7 +913,8 @@ TEST_F(ThrottlingURLLoaderTest, PauseResumeReadingBodyFromNet) {
904913
EXPECT_EQ(1u, factory_.resume_reading_body_from_net_called());
905914
}
906915

907-
TEST_F(ThrottlingURLLoaderTest, DestroyingThrottlingURLLoaderInDelegateCall) {
916+
TEST_F(ThrottlingURLLoaderTest,
917+
DestroyingThrottlingURLLoaderInDelegateCall_Response) {
908918
base::RunLoop run_loop1;
909919
throttle_->set_will_process_response_callback(base::Bind(
910920
[](const base::Closure& quit_closure,
@@ -953,5 +963,54 @@ TEST_F(ThrottlingURLLoaderTest, DestroyingThrottlingURLLoaderInDelegateCall) {
953963
EXPECT_EQ(nullptr, throttle_);
954964
}
955965

966+
// Regression test for crbug.com/833292.
967+
TEST_F(ThrottlingURLLoaderTest,
968+
DestroyingThrottlingURLLoaderInDelegateCall_Redirect) {
969+
base::RunLoop run_loop1;
970+
throttle_->set_will_redirect_request_callback(base::BindRepeating(
971+
[](const base::RepeatingClosure& quit_closure,
972+
URLLoaderThrottle::Delegate* delegate, bool* defer) {
973+
*defer = true;
974+
quit_closure.Run();
975+
},
976+
run_loop1.QuitClosure()));
977+
978+
base::RunLoop run_loop2;
979+
client_.set_on_received_redirect_callback(base::BindRepeating(
980+
[](ThrottlingURLLoaderTest* test,
981+
const base::RepeatingClosure& quit_closure) {
982+
// Destroy the ThrottlingURLLoader while inside a delegate call from a
983+
// throttle.
984+
test->loader().reset();
985+
986+
// The throttle should stay alive.
987+
EXPECT_NE(nullptr, test->throttle());
988+
989+
quit_closure.Run();
990+
},
991+
base::Unretained(this), run_loop2.QuitClosure()));
992+
993+
CreateLoaderAndStart();
994+
995+
factory_.NotifyClientOnReceiveRedirect();
996+
997+
run_loop1.Run();
998+
999+
EXPECT_EQ(1u, throttle_->will_start_request_called());
1000+
EXPECT_EQ(1u, throttle_->will_redirect_request_called());
1001+
EXPECT_EQ(0u, throttle_->will_process_response_called());
1002+
1003+
throttle_->delegate()->Resume();
1004+
run_loop2.Run();
1005+
1006+
// The ThrottlingURLLoader should be gone.
1007+
EXPECT_EQ(nullptr, loader_);
1008+
// The throttle should stay alive and destroyed later.
1009+
EXPECT_NE(nullptr, throttle_);
1010+
1011+
scoped_task_environment_.RunUntilIdle();
1012+
EXPECT_EQ(nullptr, throttle_);
1013+
}
1014+
9561015
} // namespace
9571016
} // namespace content

0 commit comments

Comments
 (0)