Index: extensions/browser/content_verifier.cc |
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc |
index 1e164ea43390417bdc8f95f1f87f9b5bd08bf62b..92721bbbb4de5569e5dcad9ca07858891e805c24 100644 |
--- a/extensions/browser/content_verifier.cc |
+++ b/extensions/browser/content_verifier.cc |
@@ -32,7 +32,10 @@ ContentVerifier::ContentVerifier(content::BrowserContext* context, |
: mode_(GetMode()), |
context_(context), |
delegate_(delegate), |
- fetcher_(new ContentHashFetcher(context, delegate)) { |
+ fetcher_(new ContentHashFetcher( |
+ context, |
+ delegate, |
+ base::Bind(&ContentVerifier::OnFetchComplete, this))) { |
} |
ContentVerifier::~ContentVerifier() { |
@@ -59,33 +62,11 @@ ContentVerifyJob* ContentVerifier::CreateJobFor( |
const Extension* extension = |
registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
- if (!extension || !extension->version() || |
- !delegate_->ShouldBeVerified(*extension)) |
- return NULL; |
- |
- // Images used in the browser get transcoded during install, so skip checking |
- // them for now. TODO(asargent) - see if we can cache this list for a given |
- // extension id/version pair. |
- std::set<base::FilePath> browser_images = |
- delegate_->GetBrowserImagePaths(extension); |
- if (ContainsKey(browser_images, relative_path)) |
+ std::set<base::FilePath> paths; |
+ paths.insert(relative_path); |
+ if (!ShouldVerifyAnyPaths(extension, paths)) |
return NULL; |
- base::FilePath locales_dir = extension_root.Append(kLocaleFolder); |
- base::FilePath full_path = extension_root.Append(relative_path); |
- if (locales_dir.IsParent(full_path)) { |
- // TODO(asargent) - see if we can cache this list to avoid having to fetch |
- // it every time. Maybe it can never change at runtime? (Or if it can, |
- // maybe there is an event we can listen for to know to drop our cache). |
- std::set<std::string> all_locales; |
- extension_l10n_util::GetAllLocales(&all_locales); |
- // Since message catalogs get transcoded during installation, we want to |
- // ignore only those paths that the localization transcoding *did* ignore. |
- if (!extension_l10n_util::ShouldSkipValidation( |
- locales_dir, full_path, all_locales)) |
- return NULL; |
- } |
- |
// TODO(asargent) - we can probably get some good performance wins by having |
// a cache of ContentHashReader's that we hold onto past the end of each job. |
return new ContentVerifyJob( |
@@ -107,21 +88,96 @@ void ContentVerifier::VerifyFailed(const std::string& extension_id, |
return; |
} |
- if (!delegate_ || mode_ < ENFORCE) |
+ VLOG(1) << "VerifyFailed " << extension_id << " reason:" << reason; |
+ |
+ if (!delegate_ || !fetcher_.get() || mode_ < ENFORCE) |
return; |
- if (reason == ContentVerifyJob::NO_HASHES && mode_ < ENFORCE_STRICT && |
- fetcher_.get()) { |
+ if (reason == ContentVerifyJob::MISSING_ALL_HASHES) { |
// If we failed because there were no hashes yet for this extension, just |
// request some. |
ExtensionRegistry* registry = ExtensionRegistry::Get(context_); |
const Extension* extension = |
registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
if (extension) |
- fetcher_->DoFetch(extension); |
+ fetcher_->DoFetch(extension, true /* force */); |
+ } else { |
+ delegate_->VerifyFailed(extension_id); |
+ } |
+} |
+ |
+void ContentVerifier::OnFetchComplete( |
+ const std::string& extension_id, |
+ bool success, |
+ bool was_force_check, |
+ const std::set<base::FilePath>& hash_mismatch_paths) { |
+ VLOG(1) << "OnFetchComplete " << extension_id << " success:" << success; |
+ |
+ if (!delegate_ || mode_ < ENFORCE) |
return; |
+ |
+ if (!success && mode_ < ENFORCE_STRICT) |
+ return; |
+ |
+ ExtensionRegistry* registry = ExtensionRegistry::Get(context_); |
+ const Extension* extension = |
+ registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
+ if (!extension) |
+ return; |
+ |
+ if ((was_force_check && !success) || |
+ ShouldVerifyAnyPaths(extension, hash_mismatch_paths)) |
+ delegate_->VerifyFailed(extension_id); |
+} |
+ |
+bool ContentVerifier::ShouldVerifyAnyPaths( |
+ const Extension* extension, |
+ const std::set<base::FilePath>& relative_paths) { |
+ if (!extension || !extension->version() || |
+ !delegate_->ShouldBeVerified(*extension)) |
+ return false; |
+ |
+ // Images used in the browser get transcoded during install, so skip |
+ // checking them for now. TODO(asargent) - see if we can cache this list |
+ // for a given extension id/version pair. |
+ std::set<base::FilePath> browser_images = |
+ delegate_->GetBrowserImagePaths(extension); |
+ |
+ base::FilePath locales_dir = extension->path().Append(kLocaleFolder); |
+ scoped_ptr<std::set<std::string> > all_locales; |
+ |
+ for (std::set<base::FilePath>::const_iterator i = relative_paths.begin(); |
+ i != relative_paths.end(); |
+ ++i) { |
+ const base::FilePath& relative_path = *i; |
+ |
+ if (relative_path == base::FilePath(kManifestFilename)) |
+ continue; |
+ |
+ if (ContainsKey(browser_images, relative_path)) |
+ continue; |
+ |
+ base::FilePath full_path = extension->path().Append(relative_path); |
+ if (locales_dir.IsParent(full_path)) { |
+ if (!all_locales) { |
+ // TODO(asargent) - see if we can cache this list longer to avoid |
+ // having to fetch it more than once for a given run of the |
+ // browser. Maybe it can never change at runtime? (Or if it can, maybe |
+ // there is an event we can listen for to know to drop our cache). |
+ all_locales.reset(new std::set<std::string>); |
+ extension_l10n_util::GetAllLocales(all_locales.get()); |
+ } |
+ |
+ // Since message catalogs get transcoded during installation, we want |
+ // to skip those paths. |
+ if (full_path.DirName().DirName() == locales_dir && |
+ !extension_l10n_util::ShouldSkipValidation( |
+ locales_dir, full_path.DirName(), *all_locales)) |
+ continue; |
+ } |
+ return true; |
} |
- delegate_->VerifyFailed(extension_id); |
+ return false; |
} |
// static |