summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_updater.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions/extension_updater.cc')
-rw-r--r--chrome/browser/extensions/extension_updater.cc69
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));