fix: dangling pointer in webRequest callbacks

This commit is contained in:
Shelley Vohr 2024-06-24 17:02:28 +02:00
Родитель 66b8b79229
Коммит 67dfc85442
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: F13993A75599653C
4 изменённых файлов: 20 добавлений и 17 удалений

Просмотреть файл

@ -99,6 +99,8 @@ ProxyingURLLoaderFactory::InProgressRequest::~InProgressRequest() {
std::move(on_headers_received_callback_) std::move(on_headers_received_callback_)
.Run(net::ERR_ABORTED, std::nullopt, std::nullopt); .Run(net::ERR_ABORTED, std::nullopt, std::nullopt);
} }
// delete redirect_url_;
} }
void ProxyingURLLoaderFactory::InProgressRequest::Restart() { void ProxyingURLLoaderFactory::InProgressRequest::Restart() {
@ -147,9 +149,9 @@ void ProxyingURLLoaderFactory::InProgressRequest::RestartInternal() {
base::BindRepeating(&InProgressRequest::ContinueToBeforeSendHeaders, base::BindRepeating(&InProgressRequest::ContinueToBeforeSendHeaders,
weak_factory_.GetWeakPtr()); weak_factory_.GetWeakPtr());
} }
redirect_url_ = GURL(); *redirect_url_ = GURL();
int result = factory_->web_request_api()->OnBeforeRequest( int result = factory_->web_request_api()->OnBeforeRequest(
&info_.value(), request_, continuation, &redirect_url_); &info_.value(), request_, continuation, redirect_url_);
if (result == net::ERR_BLOCKED_BY_CLIENT) { if (result == net::ERR_BLOCKED_BY_CLIENT) {
// The request was cancelled synchronously. Dispatch an error notification // The request was cancelled synchronously. Dispatch an error notification
// and terminate the request. // and terminate the request.
@ -396,16 +398,16 @@ void ProxyingURLLoaderFactory::InProgressRequest::
net::RedirectInfo redirect_info; net::RedirectInfo redirect_info;
redirect_info.status_code = kInternalRedirectStatusCode; redirect_info.status_code = kInternalRedirectStatusCode;
redirect_info.new_method = request_.method; redirect_info.new_method = request_.method;
redirect_info.new_url = redirect_url_; redirect_info.new_url = *redirect_url_;
redirect_info.new_site_for_cookies = redirect_info.new_site_for_cookies =
net::SiteForCookies::FromUrl(redirect_url_); net::SiteForCookies::FromUrl(*redirect_url_);
auto head = network::mojom::URLResponseHead::New(); auto head = network::mojom::URLResponseHead::New();
std::string headers = base::StringPrintf( std::string headers = base::StringPrintf(
"HTTP/1.1 %i Internal Redirect\n" "HTTP/1.1 %i Internal Redirect\n"
"Location: %s\n" "Location: %s\n"
"Non-Authoritative-Reason: WebRequest API\n\n", "Non-Authoritative-Reason: WebRequest API\n\n",
kInternalRedirectStatusCode, redirect_url_.spec().c_str()); kInternalRedirectStatusCode, redirect_url_->spec().c_str());
// Cross-origin requests need to modify the Origin header to 'null'. Since // Cross-origin requests need to modify the Origin header to 'null'. Since
// CorsURLLoader sets |request_initiator| to the Origin request header in // CorsURLLoader sets |request_initiator| to the Origin request header in
@ -414,7 +416,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::
// Following checks implement the step 10 of "4.4. HTTP-redirect fetch", // Following checks implement the step 10 of "4.4. HTTP-redirect fetch",
// https://fetch.spec.whatwg.org/#http-redirect-fetch // https://fetch.spec.whatwg.org/#http-redirect-fetch
if (request_.request_initiator && if (request_.request_initiator &&
(!url::Origin::Create(redirect_url_) (!url::Origin::Create(*redirect_url_)
.IsSameOriginWith(url::Origin::Create(request_.url)) && .IsSameOriginWith(url::Origin::Create(request_.url)) &&
!request_.request_initiator->IsSameOriginWith( !request_.request_initiator->IsSameOriginWith(
url::Origin::Create(request_.url)))) { url::Origin::Create(request_.url)))) {
@ -436,7 +438,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeSendHeaders(
return; return;
} }
if (!current_request_uses_header_client_ && !redirect_url_.is_empty()) { if (!current_request_uses_header_client_ && !redirect_url_->is_empty()) {
if (for_cors_preflight_) { if (for_cors_preflight_) {
// CORS preflight doesn't support redirect. // CORS preflight doesn't support redirect.
OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED)); OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED));
@ -485,7 +487,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToStartRequest(
return; return;
} }
if (current_request_uses_header_client_ && !redirect_url_.is_empty()) { if (current_request_uses_header_client_ && !redirect_url_->is_empty()) {
HandleBeforeRequestRedirect(); HandleBeforeRequestRedirect();
return; return;
} }
@ -592,12 +594,13 @@ void ProxyingURLLoaderFactory::InProgressRequest::
} }
} }
if (for_cors_preflight_ && !redirect_url_.is_empty()) { if (for_cors_preflight_ && !redirect_url_->is_empty()) {
OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED)); OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED));
return; return;
} }
std::move(on_headers_received_callback_).Run(net::OK, headers, redirect_url_); std::move(on_headers_received_callback_)
.Run(net::OK, headers, *redirect_url_);
override_headers_ = nullptr; override_headers_ = nullptr;
if (for_cors_preflight_) { if (for_cors_preflight_) {
@ -701,7 +704,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeRedirect(
void ProxyingURLLoaderFactory::InProgressRequest:: void ProxyingURLLoaderFactory::InProgressRequest::
HandleResponseOrRedirectHeaders(net::CompletionOnceCallback continuation) { HandleResponseOrRedirectHeaders(net::CompletionOnceCallback continuation) {
override_headers_ = nullptr; override_headers_ = nullptr;
redirect_url_ = GURL(); *redirect_url_ = GURL();
info_->AddResponseInfoFromResourceResponse(*current_response_); info_->AddResponseInfoFromResourceResponse(*current_response_);
@ -709,7 +712,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::
DCHECK(info_.has_value()); DCHECK(info_.has_value());
int result = factory_->web_request_api()->OnHeadersReceived( int result = factory_->web_request_api()->OnHeadersReceived(
&info_.value(), request_, std::move(callback_pair.first), &info_.value(), request_, std::move(callback_pair.first),
current_response_->headers.get(), &override_headers_, &redirect_url_); current_response_->headers.get(), &override_headers_, redirect_url_);
if (result == net::ERR_BLOCKED_BY_CLIENT) { if (result == net::ERR_BLOCKED_BY_CLIENT) {
OnRequestError(network::URLLoaderCompletionStatus(result)); OnRequestError(network::URLLoaderCompletionStatus(result));
return; return;

Просмотреть файл

@ -153,7 +153,7 @@ class ProxyingURLLoaderFactory
network::mojom::URLResponseHeadPtr current_response_; network::mojom::URLResponseHeadPtr current_response_;
mojo::ScopedDataPipeConsumerHandle current_body_; mojo::ScopedDataPipeConsumerHandle current_body_;
scoped_refptr<net::HttpResponseHeaders> override_headers_; scoped_refptr<net::HttpResponseHeaders> override_headers_;
GURL redirect_url_; raw_ptr<GURL> redirect_url_ = new GURL{};
const bool for_cors_preflight_ = false; const bool for_cors_preflight_ = false;

Просмотреть файл

@ -72,7 +72,7 @@ void ProxyingWebSocket::Start() {
} }
int result = web_request_api_->OnBeforeRequest(&info_, request_, continuation, int result = web_request_api_->OnBeforeRequest(&info_, request_, continuation,
&redirect_url_); redirect_url_);
if (result == net::ERR_BLOCKED_BY_CLIENT) { if (result == net::ERR_BLOCKED_BY_CLIENT) {
OnError(result); OnError(result);
@ -100,7 +100,7 @@ void ProxyingWebSocket::ContinueToHeadersReceived() {
info_.AddResponseInfoFromResourceResponse(*response_); info_.AddResponseInfoFromResourceResponse(*response_);
int result = web_request_api_->OnHeadersReceived( int result = web_request_api_->OnHeadersReceived(
&info_, request_, continuation, response_->headers.get(), &info_, request_, continuation, response_->headers.get(),
&override_headers_, &redirect_url_); &override_headers_, redirect_url_);
if (result == net::ERR_BLOCKED_BY_CLIENT) { if (result == net::ERR_BLOCKED_BY_CLIENT) {
OnError(result); OnError(result);
@ -188,7 +188,7 @@ void ProxyingWebSocket::OnAuthRequired(
info_.AddResponseInfoFromResourceResponse(*response_); info_.AddResponseInfoFromResourceResponse(*response_);
int result = web_request_api_->OnHeadersReceived( int result = web_request_api_->OnHeadersReceived(
&info_, request_, continuation, response_->headers.get(), &info_, request_, continuation, response_->headers.get(),
&override_headers_, &redirect_url_); &override_headers_, redirect_url_);
if (result == net::ERR_BLOCKED_BY_CLIENT) { if (result == net::ERR_BLOCKED_BY_CLIENT) {
OnError(result); OnError(result);

Просмотреть файл

@ -163,7 +163,7 @@ class ProxyingWebSocket : public network::mojom::WebSocketHandshakeClient,
OnBeforeSendHeadersCallback on_before_send_headers_callback_; OnBeforeSendHeadersCallback on_before_send_headers_callback_;
OnHeadersReceivedCallback on_headers_received_callback_; OnHeadersReceivedCallback on_headers_received_callback_;
GURL redirect_url_; raw_ptr<GURL> redirect_url_ = new GURL{};
bool is_done_ = false; bool is_done_ = false;
bool has_extra_headers_; bool has_extra_headers_;
mojo::PendingRemote<network::mojom::WebSocket> websocket_; mojo::PendingRemote<network::mojom::WebSocket> websocket_;