diff options
Diffstat (limited to 'chrome/browser/extensions/extension_updater.cc')
-rw-r--r-- | chrome/browser/extensions/extension_updater.cc | 69 |
1 files changed, 57 insertions, 12 deletions
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc index b2b3972..573da94 100644 --- a/chrome/browser/extensions/extension_updater.cc +++ b/chrome/browser/extensions/extension_updater.cc @@ -97,7 +97,8 @@ ManifestFetchData::~ManifestFetchData() {} // // (Note that '=' is %3D and '&' is %26 when urlencoded.) bool ManifestFetchData::AddExtension(std::string id, std::string version, - int days) { + int days, + const std::string& update_url_data) { if (extension_ids_.find(id) != extension_ids_.end()) { NOTREACHED() << "Duplicate extension id " << id; return false; @@ -109,6 +110,13 @@ bool ManifestFetchData::AddExtension(std::string id, std::string version, parts.push_back("v=" + version); parts.push_back("uc"); + if (!update_url_data.empty()) { + // Make sure the update_url_data string is escaped before using it so that + // there is no chance of overriding the id or v other parameter value + // we place into the x= value. + parts.push_back("ap=" + EscapeQueryParamValue(update_url_data, true)); + } + if (ShouldPing(days)) { parts.push_back("ping=" + EscapeQueryParamValue("r=" + base::IntToString(days), true)); @@ -177,12 +185,20 @@ void ManifestFetchesBuilder::AddExtension(const Extension& extension) { return; } + // If the extension updates itself from the gallery, ignore any update URL + // data. At the moment there is no extra data that an extension can + // communicate to the the gallery update servers. + std::string update_url_data; + if (!extension.UpdatesFromGallery()) + update_url_data = service_->extension_prefs()-> + GetUpdateUrlData(extension.id()); + AddExtensionData(extension.location(), extension.id(), *extension.version(), (extension.is_theme() ? PendingExtensionInfo::THEME : PendingExtensionInfo::EXTENSION), - extension.update_url()); + extension.update_url(), update_url_data); } void ManifestFetchesBuilder::AddPendingExtension( @@ -195,7 +211,7 @@ void ManifestFetchesBuilder::AddPendingExtension( Version::GetVersionFromString("0.0.0.0")); AddExtensionData(info.install_source, id, *version, - info.expected_crx_type, info.update_url); + info.expected_crx_type, info.update_url, ""); } void ManifestFetchesBuilder::ReportStats() const { @@ -230,7 +246,8 @@ void ManifestFetchesBuilder::AddExtensionData( const std::string& id, const Version& version, PendingExtensionInfo::ExpectedCrxType crx_type, - GURL update_url) { + GURL update_url, + const std::string& update_url_data) { if (!Extension::IsAutoUpdateableLocation(location)) { return; @@ -277,7 +294,7 @@ void ManifestFetchesBuilder::AddExtensionData( CalculatePingDays(service_->extension_prefs()->LastPingDay(id)); while (existing_iter != fetches_.end()) { if (existing_iter->second->AddExtension(id, version.GetString(), - ping_days)) { + ping_days, update_url_data)) { fetch = existing_iter->second; break; } @@ -286,7 +303,8 @@ void ManifestFetchesBuilder::AddExtensionData( if (!fetch) { fetch = new ManifestFetchData(update_url); fetches_.insert(std::pair<GURL, ManifestFetchData*>(update_url, fetch)); - bool added = fetch->AddExtension(id, version.GetString(), ping_days); + bool added = fetch->AddExtension(id, version.GetString(), ping_days, + update_url_data); DCHECK(added); } } @@ -333,7 +351,7 @@ class ExtensionUpdaterFileHandler ExtensionUpdater::ExtensionUpdater(ExtensionUpdateService* service, PrefService* prefs, int frequency_seconds) - : service_(service), frequency_seconds_(frequency_seconds), + : alive_(false), service_(service), frequency_seconds_(frequency_seconds), prefs_(prefs), file_handler_(new ExtensionUpdaterFileHandler()), blacklist_checks_enabled_(true) { Init(); @@ -350,7 +368,7 @@ void ExtensionUpdater::Init() { } ExtensionUpdater::~ExtensionUpdater() { - STLDeleteElements(&manifests_pending_); + Stop(); } static void EnsureInt64PrefRegistered(PrefService* prefs, @@ -367,6 +385,7 @@ static void EnsureBlacklistVersionPrefRegistered(PrefService* prefs) { // The overall goal here is to balance keeping clients up to date while // avoiding a thundering herd against update servers. TimeDelta ExtensionUpdater::DetermineFirstCheckDelay() { + DCHECK(alive_); // If someone's testing with a quick frequency, just allow it. if (frequency_seconds_ < kStartupWaitSeconds) return TimeDelta::FromSeconds(frequency_seconds_); @@ -409,6 +428,12 @@ TimeDelta ExtensionUpdater::DetermineFirstCheckDelay() { } void ExtensionUpdater::Start() { + DCHECK(!alive_); + // If these are NULL, then that means we've been called after Stop() + // has been called. + DCHECK(service_); + DCHECK(prefs_); + alive_ = true; // Make sure our prefs are registered, then schedule the first check. EnsureInt64PrefRegistered(prefs_, kLastExtensionsUpdateCheck); EnsureInt64PrefRegistered(prefs_, kNextExtensionsUpdateCheck); @@ -417,9 +442,13 @@ void ExtensionUpdater::Start() { } void ExtensionUpdater::Stop() { + alive_ = false; + service_ = NULL; + prefs_ = NULL; timer_.Stop(); manifest_fetcher_.reset(); extension_fetcher_.reset(); + STLDeleteElements(&manifests_pending_); manifests_pending_.clear(); extensions_pending_.clear(); } @@ -428,6 +457,10 @@ void ExtensionUpdater::OnURLFetchComplete( const URLFetcher* source, const GURL& url, const URLRequestStatus& status, int response_code, const ResponseCookies& cookies, const std::string& data) { + // Stop() destroys all our URLFetchers, which means we shouldn't be + // called after Stop() is called. + DCHECK(alive_); + if (source == manifest_fetcher_.get()) { OnManifestFetchComplete(url, status, response_code, data); } else if (source == extension_fetcher_.get()) { @@ -540,6 +573,9 @@ void ExtensionUpdater::OnManifestFetchComplete(const GURL& url, void ExtensionUpdater::HandleManifestResults( const ManifestFetchData& fetch_data, const UpdateManifest::Results& results) { + // This can be called after we've been stopped. + if (!alive_) + return; // Examine the parsed manifest and kick off fetches of any new crx files. std::vector<int> updates = DetermineUpdates(fetch_data, results); @@ -572,6 +608,7 @@ void ExtensionUpdater::HandleManifestResults( } void ExtensionUpdater::ProcessBlacklist(const std::string& data) { + DCHECK(alive_); // Verify sha256 hash value. char sha256_hash_value[base::SHA256_LENGTH]; base::SHA256HashString(data, sha256_hash_value, base::SHA256_LENGTH); @@ -635,6 +672,9 @@ void ExtensionUpdater::OnCRXFetchComplete(const GURL& url, void ExtensionUpdater::OnCRXFileWritten(const std::string& id, const FilePath& path, const GURL& download_url) { + // This can be called after we've been stopped. + if (!alive_) + return; // The ExtensionsService is now responsible for cleaning up the temp file // at |path|. service_->UpdateExtension(id, path, download_url); @@ -642,6 +682,7 @@ void ExtensionUpdater::OnCRXFileWritten(const std::string& id, void ExtensionUpdater::ScheduleNextCheck(const TimeDelta& target_delay) { + DCHECK(alive_); DCHECK(!timer_.IsRunning()); DCHECK(target_delay >= TimeDelta::FromSeconds(1)); @@ -661,6 +702,7 @@ void ExtensionUpdater::ScheduleNextCheck(const TimeDelta& target_delay) { } void ExtensionUpdater::TimerFired() { + DCHECK(alive_); CheckNow(); // If the user has overridden the update frequency, don't bother reporting @@ -685,6 +727,7 @@ void ExtensionUpdater::TimerFired() { } void ExtensionUpdater::CheckNow() { + DCHECK(alive_); ManifestFetchesBuilder fetches_builder(service_); const ExtensionList* extensions = service_->extensions(); @@ -711,7 +754,7 @@ void ExtensionUpdater::CheckNow() { std::string version = prefs_->GetString(kExtensionBlacklistUpdateVersion); int ping_days = CalculatePingDays(service_->extension_prefs()->BlacklistLastPingDay()); - blacklist_fetch->AddExtension(kBlacklistAppID, version, ping_days); + blacklist_fetch->AddExtension(kBlacklistAppID, version, ping_days, ""); StartUpdateCheck(blacklist_fetch); } @@ -730,6 +773,7 @@ void ExtensionUpdater::CheckNow() { bool ExtensionUpdater::GetExistingVersion(const std::string& id, std::string* version) { + DCHECK(alive_); if (id == kBlacklistAppID) { *version = prefs_->GetString(kExtensionBlacklistUpdateVersion); return true; @@ -745,6 +789,7 @@ bool ExtensionUpdater::GetExistingVersion(const std::string& id, std::vector<int> ExtensionUpdater::DetermineUpdates( const ManifestFetchData& fetch_data, const UpdateManifest::Results& possible_updates) { + DCHECK(alive_); std::vector<int> result; // This will only get set if one of possible_updates specifies @@ -806,6 +851,7 @@ std::vector<int> ExtensionUpdater::DetermineUpdates( } void ExtensionUpdater::StartUpdateCheck(ManifestFetchData* fetch_data) { + scoped_ptr<ManifestFetchData> scoped_fetch_data(fetch_data); if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableBackgroundNetworking)) return; @@ -814,20 +860,19 @@ void ExtensionUpdater::StartUpdateCheck(ManifestFetchData* fetch_data) { for (i = manifests_pending_.begin(); i != manifests_pending_.end(); i++) { if (fetch_data->full_url() == (*i)->full_url()) { // This url is already scheduled to be fetched. - delete fetch_data; return; } } if (manifest_fetcher_.get() != NULL) { if (manifest_fetcher_->url() != fetch_data->full_url()) { - manifests_pending_.push_back(fetch_data); + manifests_pending_.push_back(scoped_fetch_data.release()); } } else { UMA_HISTOGRAM_COUNTS("Extensions.UpdateCheckUrlLength", fetch_data->full_url().possibly_invalid_spec().length()); - current_manifest_fetch_.reset(fetch_data); + current_manifest_fetch_.swap(scoped_fetch_data); manifest_fetcher_.reset( URLFetcher::Create(kManifestFetcherId, fetch_data->full_url(), URLFetcher::GET, this)); |