Commit 51ac0407 authored by bryner@chromium.org's avatar bryner@chromium.org

Fix a possible crash in the ClientSideDetectionService.

This fixes a problem where if the model fetch is still running when the
ClientSideDetectionService is destroyed, the URLFetcher is not deleted.
This could potentially cause the OnURLFetchComplete callback to be called
on a deleted ClientSideDetectionService object.

Now the model fetcher will always be deleted, and we will also make sure to
destroy the ClientSideDetectionService before tearing down the IO thread
(since the URLFetcher dtor can post messages there).

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/6298004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71901 0039d316-1c4b-4281-b951-d872f2087c98
parent 8574bfc8
...@@ -146,14 +146,16 @@ BrowserProcessImpl::~BrowserProcessImpl() { ...@@ -146,14 +146,16 @@ BrowserProcessImpl::~BrowserProcessImpl() {
// any pending URLFetchers, and avoid creating any more. // any pending URLFetchers, and avoid creating any more.
SdchDictionaryFetcher::Shutdown(); SdchDictionaryFetcher::Shutdown();
// We need to destroy the MetricsService, GoogleURLTracker, and // We need to destroy the MetricsService, GoogleURLTracker,
// IntranetRedirectDetector before the io_thread_ gets destroyed, since their // IntranetRedirectDetector, and SafeBrowsing ClientSideDetectionService
// destructors can call the URLFetcher destructor, which does a // before the io_thread_ gets destroyed, since their destructors can call the
// PostDelayedTask operation on the IO thread. (The IO thread will handle // URLFetcher destructor, which does a PostDelayedTask operation on the IO
// that URLFetcher operation before going away.) // thread. (The IO thread will handle that URLFetcher operation before going
// away.)
metrics_service_.reset(); metrics_service_.reset();
google_url_tracker_.reset(); google_url_tracker_.reset();
intranet_redirect_detector_.reset(); intranet_redirect_detector_.reset();
safe_browsing_detection_service_.reset();
// Need to clear the desktop notification balloons before the io_thread_ and // Need to clear the desktop notification balloons before the io_thread_ and
// before the profiles, since if there are any still showing we will access // before the profiles, since if there are any still showing we will access
......
...@@ -40,7 +40,6 @@ ClientSideDetectionService::ClientSideDetectionService( ...@@ -40,7 +40,6 @@ ClientSideDetectionService::ClientSideDetectionService(
: model_path_(model_path), : model_path_(model_path),
model_status_(UNKNOWN_STATUS), model_status_(UNKNOWN_STATUS),
model_file_(base::kInvalidPlatformFileValue), model_file_(base::kInvalidPlatformFileValue),
model_fetcher_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
request_context_getter_(request_context_getter) { request_context_getter_(request_context_getter) {
...@@ -105,17 +104,14 @@ void ClientSideDetectionService::OnURLFetchComplete( ...@@ -105,17 +104,14 @@ void ClientSideDetectionService::OnURLFetchComplete(
int response_code, int response_code,
const ResponseCookies& cookies, const ResponseCookies& cookies,
const std::string& data) { const std::string& data) {
if (source == model_fetcher_) { if (source == model_fetcher_.get()) {
HandleModelResponse(source, url, status, response_code, cookies, data); HandleModelResponse(source, url, status, response_code, cookies, data);
// The fetcher object will be invalid after this method returns.
model_fetcher_ = NULL;
} else if (client_phishing_reports_.find(source) != } else if (client_phishing_reports_.find(source) !=
client_phishing_reports_.end()) { client_phishing_reports_.end()) {
HandlePhishingVerdict(source, url, status, response_code, cookies, data); HandlePhishingVerdict(source, url, status, response_code, cookies, data);
} else { } else {
NOTREACHED(); NOTREACHED();
} }
delete source;
} }
void ClientSideDetectionService::SetModelStatus(ModelStatus status) { void ClientSideDetectionService::SetModelStatus(ModelStatus status) {
...@@ -142,10 +138,10 @@ void ClientSideDetectionService::OpenModelFileDone( ...@@ -142,10 +138,10 @@ void ClientSideDetectionService::OpenModelFileDone(
SetModelStatus(READY_STATUS); SetModelStatus(READY_STATUS);
} else if (base::PLATFORM_FILE_ERROR_NOT_FOUND == error_code) { } else if (base::PLATFORM_FILE_ERROR_NOT_FOUND == error_code) {
// We need to fetch the model since it does not exist yet. // We need to fetch the model since it does not exist yet.
model_fetcher_ = URLFetcher::Create(0 /* ID is not used */, model_fetcher_.reset(URLFetcher::Create(0 /* ID is not used */,
GURL(kClientModelUrl), GURL(kClientModelUrl),
URLFetcher::GET, URLFetcher::GET,
this); this));
model_fetcher_->set_request_context(request_context_getter_.get()); model_fetcher_->set_request_context(request_context_getter_.get());
model_fetcher_->Start(); model_fetcher_->Start();
} else { } else {
...@@ -304,6 +300,7 @@ void ClientSideDetectionService::HandlePhishingVerdict( ...@@ -304,6 +300,7 @@ void ClientSideDetectionService::HandlePhishingVerdict(
info->callback->Run(info->phishing_url, false); info->callback->Run(info->phishing_url, false);
} }
client_phishing_reports_.erase(source); client_phishing_reports_.erase(source);
delete source;
} }
} // namespace safe_browsing } // namespace safe_browsing
...@@ -165,7 +165,7 @@ class ClientSideDetectionService : public URLFetcher::Delegate { ...@@ -165,7 +165,7 @@ class ClientSideDetectionService : public URLFetcher::Delegate {
FilePath model_path_; FilePath model_path_;
ModelStatus model_status_; ModelStatus model_status_;
base::PlatformFile model_file_; base::PlatformFile model_file_;
URLFetcher* model_fetcher_; scoped_ptr<URLFetcher> model_fetcher_;
scoped_ptr<std::string> tmp_model_string_; scoped_ptr<std::string> tmp_model_string_;
std::vector<OpenModelDoneCallback*> open_callbacks_; std::vector<OpenModelDoneCallback*> open_callbacks_;
......
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