Fix crash in ProxyURLLoaderFactory::MaybeDestroySelf (see issue #2622).

This is a speculative fix for a crash where |on_disconnect_| appears to be null
in ProxyURLLoaderFactory::MaybeDestroySelf. The hypothesis here is that
OnURLLoaderClientError is being called while the proxy object is still in-flight
to ResourceContextData::AddProxy (e.g. before SetDisconnectCallback has been
called for the proxy object). Additonally, this change protects against
MaybeDestroySelf attempting to execute |on_disconnect_| multiple times.
This commit is contained in:
Marshall Greenblatt 2019-06-14 18:52:28 +02:00
parent f0c82200ba
commit 81064faac3
2 changed files with 16 additions and 2 deletions

View File

@ -59,6 +59,12 @@ class ResourceContextData : public base::SupportsUserData::Data {
content::ResourceContext* resource_context) {
CEF_REQUIRE_IOT();
// Maybe the proxy was destroyed while AddProxyOnUIThread was pending.
if (proxy->destroyed_) {
delete proxy;
return;
}
auto* self = static_cast<ResourceContextData*>(
resource_context->GetUserData(kResourceContextUserDataKey));
if (!self) {
@ -1046,6 +1052,7 @@ void ProxyURLLoaderFactory::CreateOnIOThread(
void ProxyURLLoaderFactory::SetDisconnectCallback(
DisconnectCallback on_disconnect) {
CEF_REQUIRE_IOT();
DCHECK(!destroyed_);
DCHECK(!on_disconnect_);
on_disconnect_ = std::move(on_disconnect);
}
@ -1179,8 +1186,14 @@ void ProxyURLLoaderFactory::MaybeDestroySelf() {
if (target_factory_.is_bound() || !requests_.empty())
return;
// Deletes |this|.
std::move(on_disconnect_).Run(this);
CHECK(!destroyed_);
destroyed_ = true;
// In some cases we may be destroyed before SetDisconnectCallback is called.
if (on_disconnect_) {
// Deletes |this|.
std::move(on_disconnect_).Run(this);
}
}
} // namespace net_service

View File

@ -195,6 +195,7 @@ class ProxyURLLoaderFactory
std::unique_ptr<InterceptedRequestHandler> request_handler_;
bool destroyed_ = false;
DisconnectCallback on_disconnect_;
// Map of request ID to request object.