diff options
author | mkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-23 10:58:42 +0000 |
---|---|---|
committer | mkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-23 10:58:42 +0000 |
commit | 1747eac07a8a2b42f1879be727e686d238f2e363 (patch) | |
tree | e98a074cef8eff8e16943f6e2eac0fe09f9ce357 | |
parent | 237781df23071813168d4906fd85739e2b70e3ee (diff) | |
download | chromium_src-1747eac07a8a2b42f1879be727e686d238f2e363.zip chromium_src-1747eac07a8a2b42f1879be727e686d238f2e363.tar.gz chromium_src-1747eac07a8a2b42f1879be727e686d238f2e363.tar.bz2 |
Revert r224680: "Delete the omahaproxy-backed extension blacklist"
This broke the ASAN bots: http://build.chromium.org/p/chromium.memory/builders/Linux%20ASAN%20Tests%20%282%29/builds/17641/steps/unit_tests/logs/stdio
> Revert "LSan suppressions after r224680: `BlacklistTest.*`."
>
> This reverts commit 06bbf1b9dd714ca64d14d2deae758ae60968b8c9.
>
> Revert "Delete the omahaproxy-backed extension blacklist and clear its entries from the"
>
> This reverts commit e636c811a9d9814d39dd3842d6ee4516353fbd1f.
BUG=296828
TBR=kalman@chromium.org
Review URL: https://codereview.chromium.org/23497010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@224702 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 985 insertions, 435 deletions
diff --git a/chrome/browser/chromeos/extensions/external_cache.cc b/chrome/browser/chromeos/extensions/external_cache.cc index eb47ec2..edda312 100644 --- a/chrome/browser/chromeos/extensions/external_cache.cc +++ b/chrome/browser/chromeos/extensions/external_cache.cc @@ -163,6 +163,15 @@ void ExternalCache::OnExtensionDownloadFinished( std::string(version))); } +void ExternalCache::OnBlacklistDownloadFinished( + const std::string& data, + const std::string& package_hash, + const std::string& version, + const extensions::ExtensionDownloaderDelegate::PingResult& ping_result, + const std::set<int>& request_ids) { + NOTREACHED(); +} + bool ExternalCache::IsExtensionPending(const std::string& id) { // Pending means that there is no installed version yet. return extensions_->HasKey(id) && !cached_extensions_->HasKey(id); diff --git a/chrome/browser/chromeos/extensions/external_cache.h b/chrome/browser/chromeos/extensions/external_cache.h index b69301c..8f42c42 100644 --- a/chrome/browser/chromeos/extensions/external_cache.h +++ b/chrome/browser/chromeos/extensions/external_cache.h @@ -92,6 +92,13 @@ class ExternalCache : public content::NotificationObserver, const PingResult& ping_result, const std::set<int>& request_ids) OVERRIDE; + virtual void OnBlacklistDownloadFinished( + const std::string& data, + const std::string& package_hash, + const std::string& version, + const PingResult& ping_result, + const std::set<int>& request_ids) OVERRIDE; + virtual bool IsExtensionPending(const std::string& id) OVERRIDE; virtual bool GetExtensionExistingVersion(const std::string& id, diff --git a/chrome/browser/extensions/api/management/management_browsertest.cc b/chrome/browser/extensions/api/management/management_browsertest.cc index ad12efc..999ae85 100644 --- a/chrome/browser/extensions/api/management/management_browsertest.cc +++ b/chrome/browser/extensions/api/management/management_browsertest.cc @@ -273,7 +273,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) { ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); ASSERT_EQ("1.0", extension->VersionString()); + // We don't want autoupdate blacklist checks. extensions::ExtensionUpdater::CheckParams params; + params.check_blacklist = false; params.callback = base::Bind(&NotificationListener::OnFinished, base::Unretained(¬ification_listener)); @@ -359,7 +361,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); ASSERT_EQ("1.0", extension->VersionString()); + // We don't want autoupdate blacklist checks. extensions::ExtensionUpdater::CheckParams params; + params.check_blacklist = false; params.callback = base::Bind(&NotificationListener::OnFinished, base::Unretained(¬ification_listener)); @@ -401,7 +405,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_ExternalUrlUpdate) { ExtensionService* service = extensions::ExtensionSystem::Get( browser()->profile())->extension_service(); const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; + // We don't want autoupdate blacklist checks. extensions::ExtensionUpdater::CheckParams params; + params.check_blacklist = false; base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); @@ -485,6 +491,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) { ExtensionService* service = extensions::ExtensionSystem::Get( browser()->profile())->extension_service(); const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; + // We don't want autoupdate blacklist checks. + extensions::ExtensionUpdater::CheckParams params; + params.check_blacklist = false; base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); @@ -557,6 +566,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, browser()->profile())->extension_service(); const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; extensions::ExtensionUpdater::CheckParams params; + params.check_blacklist = false; service->updater()->set_default_check_params(params); const size_t size_before = service->extensions()->size(); base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); diff --git a/chrome/browser/extensions/blacklist.cc b/chrome/browser/extensions/blacklist.cc index d69f1d9..905b67a 100644 --- a/chrome/browser/extensions/blacklist.cc +++ b/chrome/browser/extensions/blacklist.cc @@ -141,26 +141,22 @@ Blacklist::ScopedDatabaseManagerForTest::~ScopedDatabaseManagerForTest() { SetDatabaseManager(original_); } -Blacklist::Blacklist(ExtensionPrefs* prefs) { +Blacklist::Blacklist(ExtensionPrefs* prefs) : prefs_(prefs) { scoped_refptr<SafeBrowsingDatabaseManager> database_manager = g_database_manager.Get().get(); - if (database_manager) { + if (database_manager.get()) { registrar_.Add( this, chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, content::Source<SafeBrowsingDatabaseManager>(database_manager.get())); } - // Clear out the old prefs-backed blacklist, stored as empty extension entries - // with just a "blacklisted" property. + // TODO(kalman): Delete anything from the pref blacklist that is in the + // safebrowsing blacklist (of course, only entries for which the extension + // hasn't been installed). // - // TODO(kalman): Delete this block of code, see http://crbug.com/295882. - std::set<std::string> blacklisted = prefs->GetBlacklistedExtensions(); - for (std::set<std::string>::iterator it = blacklisted.begin(); - it != blacklisted.end(); ++it) { - if (!prefs->GetInstalledExtensionInfo(*it)) - prefs->DeleteExtensionPrefs(*it); - } + // Or maybe just wait until we're able to delete the pref blacklist + // altogether (when we're sure it's a strict subset of the safebrowsing one). } Blacklist::~Blacklist() { @@ -170,15 +166,35 @@ void Blacklist::GetBlacklistedIDs(const std::set<std::string>& ids, const GetBlacklistedIDsCallback& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (ids.empty() || !g_database_manager.Get().get().get()) { + if (ids.empty()) { base::MessageLoopProxy::current()->PostTask( - FROM_HERE, base::Bind(callback, std::set<std::string>())); + FROM_HERE, + base::Bind(callback, std::set<std::string>())); + return; + } + + // The blacklisted IDs are the union of those blacklisted in prefs and + // those blacklisted from safe browsing. + std::set<std::string> pref_blacklisted_ids; + for (std::set<std::string>::const_iterator it = ids.begin(); + it != ids.end(); ++it) { + if (prefs_->IsExtensionBlacklisted(*it)) + pref_blacklisted_ids.insert(*it); + } + + if (!g_database_manager.Get().get().get()) { + base::MessageLoopProxy::current()->PostTask( + FROM_HERE, base::Bind(callback, pref_blacklisted_ids)); return; } // Constructing the SafeBrowsingClientImpl begins the process of asking // safebrowsing for the blacklisted extensions. - new SafeBrowsingClientImpl(ids, callback); + new SafeBrowsingClientImpl( + ids, + base::Bind(&Blacklist::OnSafeBrowsingResponse, AsWeakPtr(), + pref_blacklisted_ids, + callback)); } void Blacklist::IsBlacklisted(const std::string& extension_id, @@ -188,6 +204,43 @@ void Blacklist::IsBlacklisted(const std::string& extension_id, GetBlacklistedIDs(check, base::Bind(&IsNotEmpty, callback)); } +void Blacklist::SetFromUpdater(const std::vector<std::string>& ids, + const std::string& version) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + std::set<std::string> ids_as_set; + for (std::vector<std::string>::const_iterator it = ids.begin(); + it != ids.end(); ++it) { + if (Extension::IdIsValid(*it)) + ids_as_set.insert(*it); + else + LOG(WARNING) << "Got invalid extension ID \"" << *it << "\""; + } + + std::set<std::string> from_prefs = prefs_->GetBlacklistedExtensions(); + + std::set<std::string> no_longer_blacklisted = + base::STLSetDifference<std::set<std::string> >(from_prefs, + ids_as_set); + std::set<std::string> not_yet_blacklisted = + base::STLSetDifference<std::set<std::string> >(ids_as_set, + from_prefs); + + for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); + it != no_longer_blacklisted.end(); ++it) { + prefs_->SetExtensionBlacklisted(*it, false); + } + for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); + it != not_yet_blacklisted.end(); ++it) { + prefs_->SetExtensionBlacklisted(*it, true); + } + + prefs_->pref_service()->SetString(prefs::kExtensionBlacklistUpdateVersion, + version); + + FOR_EACH_OBSERVER(Observer, observers_, OnBlacklistUpdated()); +} + void Blacklist::AddObserver(Observer* observer) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); observers_.AddObserver(observer); @@ -209,6 +262,19 @@ scoped_refptr<SafeBrowsingDatabaseManager> Blacklist::GetDatabaseManager() { return g_database_manager.Get().get(); } +void Blacklist::OnSafeBrowsingResponse( + const std::set<std::string>& pref_blacklisted_ids, + const GetBlacklistedIDsCallback& callback, + const std::set<std::string>& safebrowsing_blacklisted_ids) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + std::set<std::string> blacklist = pref_blacklisted_ids; + blacklist.insert(safebrowsing_blacklisted_ids.begin(), + safebrowsing_blacklisted_ids.end()); + + callback.Run(blacklist); +} + void Blacklist::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { diff --git a/chrome/browser/extensions/blacklist.h b/chrome/browser/extensions/blacklist.h index f005eaf..ed7acf4 100644 --- a/chrome/browser/extensions/blacklist.h +++ b/chrome/browser/extensions/blacklist.h @@ -21,7 +21,7 @@ namespace extensions { class Extension; class ExtensionPrefs; -// The blacklist of extensions backed by safe browsing. +// A blacklist of extensions. class Blacklist : public content::NotificationObserver, public base::SupportsWeakPtr<Blacklist> { public: @@ -62,6 +62,7 @@ class Blacklist : public content::NotificationObserver, typedef base::Callback<void(BlacklistState)> IsBlacklistedCallback; + // |prefs_| must outlive this. explicit Blacklist(ExtensionPrefs* prefs); virtual ~Blacklist(); @@ -79,6 +80,10 @@ class Blacklist : public content::NotificationObserver, void IsBlacklisted(const std::string& extension_id, const IsBlacklistedCallback& callback); + // Sets the blacklist from the updater to contain the extension IDs in |ids| + void SetFromUpdater(const std::vector<std::string>& ids, + const std::string& version); + // Adds/removes an observer to the blacklist. void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -89,6 +94,14 @@ class Blacklist : public content::NotificationObserver, scoped_refptr<SafeBrowsingDatabaseManager> database_manager); static scoped_refptr<SafeBrowsingDatabaseManager> GetDatabaseManager(); + // Handles the |safebrowsing_blacklisted_ids| response from querying the + // safebrowsing blacklist, given that we know |pref_blacklisted_ids| are + // already blacklisted. Responds to |callback| with the union. + void OnSafeBrowsingResponse( + const std::set<std::string>& pref_blacklisted_ids, + const GetBlacklistedIDsCallback& callback, + const std::set<std::string>& safebrowsing_blacklisted_ids); + // content::NotificationObserver virtual void Observe(int type, const content::NotificationSource& source, @@ -96,6 +109,10 @@ class Blacklist : public content::NotificationObserver, ObserverList<Observer> observers_; + ExtensionPrefs* const prefs_; + + std::set<std::string> prefs_blacklist_; + content::NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(Blacklist); diff --git a/chrome/browser/extensions/blacklist_unittest.cc b/chrome/browser/extensions/blacklist_unittest.cc index a8aaef0..1ccaf4c 100644 --- a/chrome/browser/extensions/blacklist_unittest.cc +++ b/chrome/browser/extensions/blacklist_unittest.cc @@ -10,152 +10,194 @@ #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" #include "chrome/browser/extensions/test_blacklist.h" #include "chrome/browser/extensions/test_extension_prefs.h" -#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" namespace extensions { namespace { -std::set<std::string> Set(const std::string& a) { - std::set<std::string> set; - set.insert(a); - return set; -} -std::set<std::string> Set(const std::string& a, const std::string& b) { - std::set<std::string> set = Set(a); - set.insert(b); - return set; -} -std::set<std::string> Set(const std::string& a, - const std::string& b, - const std::string& c) { - std::set<std::string> set = Set(a, b); - set.insert(c); - return set; -} -std::set<std::string> Set(const std::string& a, - const std::string& b, - const std::string& d, - const std::string& c) { - std::set<std::string> set = Set(a, b, c); - set.insert(d); - return set; -} - class BlacklistTest : public testing::Test { public: BlacklistTest() - : blacklist_db_(new FakeSafeBrowsingDatabaseManager(false)), - test_prefs_(base::MessageLoopProxy::current()), - scoped_blacklist_db_(blacklist_db_) {} - - protected: - ExtensionPrefs* prefs() { - return test_prefs_.prefs(); + : prefs_(message_loop_.message_loop_proxy().get()), + ui_thread_(content::BrowserThread::UI, &message_loop_), + io_thread_(content::BrowserThread::IO, &message_loop_), + safe_browsing_database_manager_(new FakeSafeBrowsingDatabaseManager()), + scoped_blacklist_database_manager_(safe_browsing_database_manager_), + blacklist_(prefs_.prefs()) {} + + bool IsBlacklisted(const Extension* extension) { + return TestBlacklist(&blacklist_).IsBlacklisted(extension->id()); } - std::string AddExtension(const std::string& id) { - return test_prefs_.AddExtension(id)->id(); - } + protected: + base::MessageLoop message_loop_; - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db_; + TestExtensionPrefs prefs_; - private: - content::TestBrowserThreadBundle browser_thread_bundle_; + content::TestBrowserThread ui_thread_; + content::TestBrowserThread io_thread_; - TestExtensionPrefs test_prefs_; + scoped_refptr<FakeSafeBrowsingDatabaseManager> + safe_browsing_database_manager_; + Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_database_manager_; - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db_; + Blacklist blacklist_; }; +TEST_F(BlacklistTest, SetFromUpdater) { + scoped_refptr<const Extension> extension_a = prefs_.AddExtension("a"); + scoped_refptr<const Extension> extension_b = prefs_.AddExtension("b"); + scoped_refptr<const Extension> extension_c = prefs_.AddExtension("c"); + scoped_refptr<const Extension> extension_d = prefs_.AddExtension("d"); + + // c, d, start blacklisted. + prefs_.prefs()->SetExtensionBlacklisted(extension_c->id(), true); + prefs_.prefs()->SetExtensionBlacklisted(extension_d->id(), true); + + EXPECT_FALSE(IsBlacklisted(extension_a.get())); + EXPECT_FALSE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_TRUE(IsBlacklisted(extension_d.get())); + + // Mix up the blacklist. + { + std::vector<std::string> blacklist; + blacklist.push_back(extension_b->id()); + blacklist.push_back(extension_c->id()); + blacklist_.SetFromUpdater(blacklist, "1"); + } + EXPECT_FALSE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_FALSE(IsBlacklisted(extension_d.get())); + + // No-op, just in case. + { + std::vector<std::string> blacklist; + blacklist.push_back(extension_b->id()); + blacklist.push_back(extension_c->id()); + blacklist_.SetFromUpdater(blacklist, "2"); + } + EXPECT_FALSE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_FALSE(IsBlacklisted(extension_d.get())); + + // Strictly increase the blacklist. + { + std::vector<std::string> blacklist; + blacklist.push_back(extension_a->id()); + blacklist.push_back(extension_b->id()); + blacklist.push_back(extension_c->id()); + blacklist.push_back(extension_d->id()); + blacklist_.SetFromUpdater(blacklist, "3"); + } + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_TRUE(IsBlacklisted(extension_d.get())); + + // Strictly decrease the blacklist. + { + std::vector<std::string> blacklist; + blacklist.push_back(extension_a->id()); + blacklist.push_back(extension_b->id()); + blacklist_.SetFromUpdater(blacklist, "4"); + } + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_FALSE(IsBlacklisted(extension_c.get())); + EXPECT_FALSE(IsBlacklisted(extension_d.get())); + + // Clear the blacklist. + { + std::vector<std::string> blacklist; + blacklist_.SetFromUpdater(blacklist, "5"); + } + EXPECT_FALSE(IsBlacklisted(extension_a.get())); + EXPECT_FALSE(IsBlacklisted(extension_b.get())); + EXPECT_FALSE(IsBlacklisted(extension_c.get())); + EXPECT_FALSE(IsBlacklisted(extension_d.get())); +} + void Assign(std::set<std::string> *to, const std::set<std::string>& from) { *to = from; } TEST_F(BlacklistTest, OnlyIncludesRequestedIDs) { - std::string a = AddExtension("a"); - std::string b = AddExtension("b"); - std::string c = AddExtension("c"); - - Blacklist blacklist(prefs()); - TestBlacklist tester(&blacklist); - - blacklist_db_->Enable(); - blacklist_db_->SetUnsafe(a, b); - - EXPECT_TRUE(tester.IsBlacklisted(a)); - EXPECT_TRUE(tester.IsBlacklisted(b)); - EXPECT_FALSE(tester.IsBlacklisted(c)); + scoped_refptr<const Extension> extension_a = prefs_.AddExtension("a"); + scoped_refptr<const Extension> extension_b = prefs_.AddExtension("b"); + scoped_refptr<const Extension> extension_c = prefs_.AddExtension("c"); + + { + std::vector<std::string> blacklist; + blacklist.push_back(extension_a->id()); + blacklist.push_back(extension_b->id()); + blacklist_.SetFromUpdater(blacklist, "1"); + base::RunLoop().RunUntilIdle(); + } - std::set<std::string> blacklisted_ids; - blacklist.GetBlacklistedIDs(Set(a, c), base::Bind(&Assign, &blacklisted_ids)); - base::RunLoop().RunUntilIdle(); + std::set<std::string> blacklist_actual; + { + std::set<std::string> blacklist_query; + blacklist_query.insert(extension_a->id()); + blacklist_query.insert(extension_c->id()); + blacklist_.GetBlacklistedIDs(blacklist_query, + base::Bind(&Assign, &blacklist_actual)); + base::RunLoop().RunUntilIdle(); + } - EXPECT_EQ(Set(a), blacklisted_ids); + std::set<std::string> blacklist_expected; + blacklist_expected.insert(extension_a->id()); + EXPECT_EQ(blacklist_expected, blacklist_actual); } -TEST_F(BlacklistTest, SafeBrowsing) { - std::string a = AddExtension("a"); - - Blacklist blacklist(prefs()); - TestBlacklist tester(&blacklist); - - EXPECT_FALSE(tester.IsBlacklisted(a)); +TEST_F(BlacklistTest, PrefsVsSafeBrowsing) { + scoped_refptr<const Extension> extension_a = prefs_.AddExtension("a"); + scoped_refptr<const Extension> extension_b = prefs_.AddExtension("b"); + scoped_refptr<const Extension> extension_c = prefs_.AddExtension("c"); + + // Prefs have a and b blacklisted, safebrowsing has b and c. + prefs_.prefs()->SetExtensionBlacklisted(extension_a->id(), true); + prefs_.prefs()->SetExtensionBlacklisted(extension_b->id(), true); + { + std::set<std::string> bc; + bc.insert(extension_b->id()); + bc.insert(extension_c->id()); + safe_browsing_database_manager_->set_unsafe_ids(bc); + } - blacklist_db_->SetUnsafe(a); - // The manager is still disabled at this point, so it won't be blacklisted. - EXPECT_FALSE(tester.IsBlacklisted(a)); + // The manager is still disabled at this point, so c won't be blacklisted. + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_FALSE(IsBlacklisted(extension_c.get())); - blacklist_db_->Enable().NotifyUpdate(); - base::RunLoop().RunUntilIdle(); // Now it should be. - EXPECT_TRUE(tester.IsBlacklisted(a)); - - blacklist_db_->ClearUnsafe().NotifyUpdate(); - // Safe browsing blacklist empty, now enabled. - EXPECT_FALSE(tester.IsBlacklisted(a)); -} - -// Tests that Blacklist clears the old prefs blacklist on startup. -TEST_F(BlacklistTest, ClearsPreferencesBlacklist) { - std::string a = AddExtension("a"); - std::string b = AddExtension("b"); - - // Blacklist an installed extension. - prefs()->SetExtensionBlacklisted(a, true); - - // Blacklist some non-installed extensions. This is what the old preferences - // blacklist looked like. - std::string c = "cccccccccccccccccccccccccccccccc"; - std::string d = "dddddddddddddddddddddddddddddddd"; - prefs()->SetExtensionBlacklisted(c, true); - prefs()->SetExtensionBlacklisted(d, true); - - EXPECT_EQ(Set(a, c, d), prefs()->GetBlacklistedExtensions()); - - Blacklist blacklist(prefs()); - TestBlacklist tester(&blacklist); - - // Blacklist has been cleared. Only the installed extension "a" left. - EXPECT_EQ(Set(a), prefs()->GetBlacklistedExtensions()); - EXPECT_TRUE(prefs()->GetInstalledExtensionInfo(a).get()); - EXPECT_TRUE(prefs()->GetInstalledExtensionInfo(b).get()); - - // "a" won't actually be *blacklisted* since it doesn't appear in - // safebrowsing. Blacklist no longer reads from prefs. This is purely a - // concern of somebody else (currently, ExtensionService). - std::set<std::string> blacklisted_ids; - blacklist.GetBlacklistedIDs(Set(a, b, c, d), - base::Bind(&Assign, &blacklisted_ids)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(std::set<std::string>(), blacklisted_ids); - - // Prefs are still unaffected for installed extensions, though. - EXPECT_TRUE(prefs()->IsExtensionBlacklisted(a)); - EXPECT_FALSE(prefs()->IsExtensionBlacklisted(b)); - EXPECT_FALSE(prefs()->IsExtensionBlacklisted(c)); - EXPECT_FALSE(prefs()->IsExtensionBlacklisted(d)); + safe_browsing_database_manager_->set_enabled(true); + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + + // Corner case: nothing in safebrowsing (but still enabled). + safe_browsing_database_manager_->set_unsafe_ids(std::set<std::string>()); + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_FALSE(IsBlacklisted(extension_c.get())); + + // Corner case: nothing in prefs. + prefs_.prefs()->SetExtensionBlacklisted(extension_a->id(), false); + prefs_.prefs()->SetExtensionBlacklisted(extension_b->id(), false); + { + std::set<std::string> bc; + bc.insert(extension_b->id()); + bc.insert(extension_c->id()); + safe_browsing_database_manager_->set_unsafe_ids(bc); + } + EXPECT_FALSE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); } -} // namespace } // namespace extensions +} // namespace diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index 105b4c6..8ebbfbe 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc @@ -9,7 +9,6 @@ #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_system.h" -#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" @@ -448,11 +447,13 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, } IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( - new FakeSafeBrowsingDatabaseManager(true)); - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); + extensions::Blacklist* blacklist = + ExtensionSystem::Get(profile())->blacklist(); - blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm"); + // Fake the blacklisting of the extension we're about to install by + // pretending that we get a blacklist update which includes it. + const std::string kId = "gllekhaobjnhgeagipipnkpmmmpchacm"; + blacklist->SetFromUpdater(std::vector<std::string>(1, kId), "some-version"); base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx") .AppendASCII("theme_hidpi.crx"); diff --git a/chrome/browser/extensions/extension_blacklist_browsertest.cc b/chrome/browser/extensions/extension_blacklist_browsertest.cc new file mode 100644 index 0000000..3f57cb6 --- /dev/null +++ b/chrome/browser/extensions/extension_blacklist_browsertest.cc @@ -0,0 +1,265 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/run_loop.h" +#include "chrome/browser/extensions/blacklist.h" +#include "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_notification_observer.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_constants.h" + +namespace extensions { + +namespace { + +// Stores the paths to CRX files of extensions, and the extension's ID. +// Use arbitrary extensions; we're just testing blacklisting behavior. +class CrxInfo { + public: + CrxInfo(const std::string& path, const std::string& id) + : path_(path), id_(id) {} + + const std::string& path() { return path_; } + const std::string& id() { return id_; } + + private: + const std::string path_; + const std::string id_; +}; + +} // namespace + +class ExtensionBlacklistBrowserTest : public ExtensionBrowserTest { + public: + ExtensionBlacklistBrowserTest() + : info_a_("install/install.crx", "ogdbpbegnmindpdjfafpmpicikegejdj"), + info_b_("autoupdate/v1.crx", "ogjcoiohnmldgjemafoockdghcjciccf"), + info_c_("hosted_app.crx", "kbmnembihfiondgfjekmnmcbddelicoi"), + // Just disable the safe browsing altogether. + // TODO(kalman): a different approach will be needed when the blacklist + // comes entirely from safe browsing. + scoped_blacklist_database_manager_( + scoped_refptr<SafeBrowsingDatabaseManager>(NULL)) {} + + virtual ~ExtensionBlacklistBrowserTest() {} + + protected: + // Returns whether |extension| is strictly safe: in one of ExtensionService's + // non-blacklisted extension sets, and not in its blacklisted extensions. + testing::AssertionResult IsSafe(const Extension* extension) { + std::string id = extension->id(); + int include_mask = ExtensionService::INCLUDE_EVERYTHING & + ~ExtensionService::INCLUDE_BLACKLISTED; + if (!extension_service()->GetExtensionById(id, include_mask)) + return testing::AssertionFailure() << id << " is safe"; + return IsInValidState(extension); + } + + // Returns whether |extension| is strictly blacklisted: in ExtensionService's + // blacklist, and not in any of its other extension sets. + testing::AssertionResult IsBlacklisted(const Extension* extension) { + std::string id = extension->id(); + if (!extension_service()->blacklisted_extensions()->Contains(id)) + return testing::AssertionFailure() << id << " is not blacklisted"; + return IsInValidState(extension); + } + + std::set<std::string> GetTestExtensionIDs() { + std::set<std::string> extension_ids; + extension_ids.insert(info_a_.id()); + extension_ids.insert(info_b_.id()); + extension_ids.insert(info_c_.id()); + return extension_ids; + } + + Blacklist* blacklist() { + return ExtensionSystem::Get(profile())->blacklist(); + } + + CrxInfo info_a_; + CrxInfo info_b_; + CrxInfo info_c_; + + private: + // Returns whether |extension| is either installed or blacklisted, but + // neither both nor neither. + testing::AssertionResult IsInValidState(const Extension* extension) { + std::string id = extension->id(); + bool is_blacklisted = + extension_service()->blacklisted_extensions()->Contains(id); + int safe_mask = ExtensionService::INCLUDE_EVERYTHING & + ~ExtensionService::INCLUDE_BLACKLISTED; + bool is_safe = extension_service()->GetExtensionById(id, safe_mask) != NULL; + if (is_blacklisted && is_safe) { + return testing::AssertionFailure() << + id << " is both safe and in blacklisted_extensions"; + } + if (!is_blacklisted && !is_safe) { + return testing::AssertionFailure() << + id << " is neither safe nor in blacklisted_extensions"; + } + return testing::AssertionSuccess(); + } + + Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_database_manager_; +}; + +// Stage 1: blacklisting when there weren't any extensions installed when the +// browser started. +IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, PRE_Blacklist) { + ExtensionNotificationObserver notifications( + content::NotificationService::AllSources(), GetTestExtensionIDs()); + + scoped_refptr<const Extension> extension_a = + InstallExtension(test_data_dir_.AppendASCII(info_a_.path()), 1); + scoped_refptr<const Extension> extension_b = + InstallExtension(test_data_dir_.AppendASCII(info_b_.path()), 1); + scoped_refptr<const Extension> extension_c = + InstallExtension(test_data_dir_.AppendASCII(info_c_.path()), 1); + + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_INSTALLED, + chrome::NOTIFICATION_EXTENSION_LOADED, + chrome::NOTIFICATION_EXTENSION_INSTALLED, + chrome::NOTIFICATION_EXTENSION_LOADED, + chrome::NOTIFICATION_EXTENSION_INSTALLED, + chrome::NOTIFICATION_EXTENSION_LOADED)); + + ASSERT_TRUE(extension_a.get()); + ASSERT_TRUE(extension_b.get()); + ASSERT_EQ(info_a_.id(), extension_a->id()); + ASSERT_EQ(info_b_.id(), extension_b->id()); + ASSERT_EQ(info_c_.id(), extension_c->id()); + + std::vector<std::string> empty_vector; + std::vector<std::string> vector_a(1, info_a_.id()); + std::vector<std::string> vector_b(1, info_b_.id()); + std::vector<std::string> vector_c(1, info_c_.id()); + std::vector<std::string> vector_ab(1, info_a_.id()); + vector_ab.push_back(info_b_.id()); + std::vector<std::string> vector_bc(1, info_b_.id()); + vector_bc.push_back(info_c_.id()); + std::vector<std::string> vector_abc(1, info_a_.id()); + vector_abc.push_back(info_b_.id()); + vector_abc.push_back(info_c_.id()); + + EXPECT_TRUE(IsSafe(extension_a.get())); + EXPECT_TRUE(IsSafe(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + + // Blacklist a and b. + blacklist()->SetFromUpdater(vector_ab, "1"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_UNLOADED, + chrome::NOTIFICATION_EXTENSION_UNLOADED)); + + // Un-blacklist a. + blacklist()->SetFromUpdater(vector_b, "2"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsSafe(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + EXPECT_TRUE( + notifications.CheckNotifications(chrome::NOTIFICATION_EXTENSION_LOADED)); + + // Blacklist a then switch with c. + blacklist()->SetFromUpdater(vector_ab, "3"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_UNLOADED)); + + blacklist()->SetFromUpdater(vector_bc, "4"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsSafe(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_LOADED, + chrome::NOTIFICATION_EXTENSION_UNLOADED)); + + // Add a to blacklist. + blacklist()->SetFromUpdater(vector_abc, "5"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_UNLOADED)); + + // Clear blacklist. + blacklist()->SetFromUpdater(empty_vector, "6"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsSafe(extension_a.get())); + EXPECT_TRUE(IsSafe(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + EXPECT_TRUE( + notifications.CheckNotifications(chrome::NOTIFICATION_EXTENSION_LOADED, + chrome::NOTIFICATION_EXTENSION_LOADED, + chrome::NOTIFICATION_EXTENSION_LOADED)); + + // Add a and b back again for the next test. + blacklist()->SetFromUpdater(vector_ab, "7"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_UNLOADED, + chrome::NOTIFICATION_EXTENSION_UNLOADED)); +} + +// Stage 2: blacklisting with extensions A and B having been installed, +// with A actually in the blacklist. +IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, Blacklist) { + ExtensionNotificationObserver notifications( + content::Source<Profile>(profile()), GetTestExtensionIDs()); + + scoped_refptr<const Extension> extension_a = + extension_service()->blacklisted_extensions()->GetByID(info_a_.id()); + ASSERT_TRUE(extension_a.get()); + + scoped_refptr<const Extension> extension_b = + extension_service()->blacklisted_extensions()->GetByID(info_b_.id()); + ASSERT_TRUE(extension_b.get()); + + scoped_refptr<const Extension> extension_c = + extension_service()->extensions()->GetByID(info_c_.id()); + ASSERT_TRUE(extension_c.get()); + + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsBlacklisted(extension_b.get())); + EXPECT_TRUE(IsSafe(extension_c.get())); + + // Make sure that we can still blacklist c and unblacklist b. + std::vector<std::string> vector_ac(1, extension_a->id()); + vector_ac.push_back(extension_c->id()); + blacklist()->SetFromUpdater(vector_ac, "8"); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(IsBlacklisted(extension_a.get())); + EXPECT_TRUE(IsSafe(extension_b.get())); + EXPECT_TRUE(IsBlacklisted(extension_c.get())); + EXPECT_TRUE(notifications.CheckNotifications( + chrome::NOTIFICATION_EXTENSION_LOADED, + chrome::NOTIFICATION_EXTENSION_UNLOADED)); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc index 8f20cfb..c6481b5 100644 --- a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc +++ b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc @@ -205,6 +205,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionDisabledGlobalErrorTest, scoped_temp_dir_.path().AppendASCII("permissions2.crx")); extensions::ExtensionUpdater::CheckParams params; + params.check_blacklist = false; service_->updater()->set_default_check_params(params); // Sync is replacing an older version, so it pends. diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 1e7ae32..500e5b8 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -414,6 +414,7 @@ ExtensionService::ExtensionService(Profile* profile, extension_prefs, profile->GetPrefs(), profile, + blacklist, update_frequency)); } @@ -3094,29 +3095,32 @@ void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() { void ExtensionService::OnBlacklistUpdated() { blacklist_->GetBlacklistedIDs( GenerateInstalledExtensionsSet()->GetIDs(), - base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); + base::Bind(&ExtensionService::ManageBlacklist, + AsWeakPtr(), + blacklisted_extensions_.GetIDs())); } -void ExtensionService::ManageBlacklist(const std::set<std::string>& updated) { +void ExtensionService::ManageBlacklist( + const std::set<std::string>& old_blacklisted_ids, + const std::set<std::string>& new_blacklisted_ids) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - std::set<std::string> before = blacklisted_extensions_.GetIDs(); std::set<std::string> no_longer_blacklisted = - base::STLSetDifference<std::set<std::string> >(before, updated); + base::STLSetDifference<std::set<std::string> >(old_blacklisted_ids, + new_blacklisted_ids); std::set<std::string> not_yet_blacklisted = - base::STLSetDifference<std::set<std::string> >(updated, before); + base::STLSetDifference<std::set<std::string> >(new_blacklisted_ids, + old_blacklisted_ids); for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); it != no_longer_blacklisted.end(); ++it) { scoped_refptr<const Extension> extension = blacklisted_extensions_.GetByID(*it); - if (!extension.get()) { - NOTREACHED() << "Extension " << *it << " no longer blacklisted, " - << "but it was never blacklisted."; + DCHECK(extension.get()) << "Extension " << *it << " no longer blacklisted, " + << "but it was never blacklisted."; + if (!extension.get()) continue; - } blacklisted_extensions_.Remove(*it); - extension_prefs_->SetExtensionBlacklisted(extension->id(), false); AddExtension(extension.get()); UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled", extension->location(), @@ -3126,13 +3130,11 @@ void ExtensionService::ManageBlacklist(const std::set<std::string>& updated) { for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); it != not_yet_blacklisted.end(); ++it) { scoped_refptr<const Extension> extension = GetInstalledExtension(*it); - if (!extension.get()) { - NOTREACHED() << "Extension " << *it << " needs to be " - << "blacklisted, but it's not installed."; + DCHECK(extension.get()) << "Extension " << *it << " needs to be " + << "blacklisted, but it's not installed."; + if (!extension.get()) continue; - } blacklisted_extensions_.Insert(extension); - extension_prefs_->SetExtensionBlacklisted(extension->id(), true); UnloadExtension(*it, extension_misc::UNLOAD_REASON_BLACKLIST); UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled", extension->location(), Manifest::NUM_LOCATIONS); diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index d026fbf..33114b2e 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -799,7 +799,8 @@ class ExtensionService // Manages the blacklisted extensions, intended as callback from // Blacklist::GetBlacklistedIDs. - void ManageBlacklist(const std::set<std::string>& blacklisted_ids); + void ManageBlacklist(const std::set<std::string>& old_blacklisted_ids, + const std::set<std::string>& new_blacklisted_ids); // Controls if installs are delayed. See comment for // |installs_delayed_for_gc_|. diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 0cf60a0c..5212209 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -31,7 +31,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/app_sync_data.h" -#include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/default_apps.h" @@ -49,7 +48,6 @@ #include "chrome/browser/extensions/external_pref_loader.h" #include "chrome/browser/extensions/external_provider_impl.h" #include "chrome/browser/extensions/external_provider_interface.h" -#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" #include "chrome/browser/extensions/install_observer.h" #include "chrome/browser/extensions/install_tracker.h" #include "chrome/browser/extensions/install_tracker_factory.h" @@ -126,11 +124,6 @@ #include "chrome/browser/chromeos/settings/device_settings_service.h" #endif -// The blacklist tests rely on safe browsing. -#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) -#define ENABLE_BLACKLIST_TESTS -#endif - using base::DictionaryValue; using base::ListValue; using base::Value; @@ -141,14 +134,12 @@ using content::IndexedDBContext; using content::PluginService; using extensions::APIPermission; using extensions::APIPermissionSet; -using extensions::Blacklist; using extensions::CrxInstaller; using extensions::Extension; using extensions::ExtensionCreator; using extensions::ExtensionPrefs; using extensions::ExtensionResource; using extensions::ExtensionSystem; -using extensions::FakeSafeBrowsingDatabaseManager; using extensions::FeatureSwitch; using extensions::Manifest; using extensions::PermissionSet; @@ -543,16 +534,6 @@ void ExtensionServiceTestBase::InitializeInstalledExtensionService( InitializeExtensionService(params); } -void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() { - base::FilePath source_install_dir = data_dir_ - .AppendASCII("good") - .AppendASCII("Extensions"); - base::FilePath pref_path = source_install_dir - .DirName() - .AppendASCII("Preferences"); - InitializeInstalledExtensionService(pref_path, source_install_dir); -} - void ExtensionServiceTestBase::InitializeEmptyExtensionService() { InitializeExtensionServiceHelper(false, true); } @@ -676,22 +657,6 @@ class ExtensionServiceTest } protected: - // Paths to some of the fake extensions. - base::FilePath good0_path() { - return data_dir_.AppendASCII("good").AppendASCII("Extensions") - .AppendASCII(good0).AppendASCII("1.0.0.0"); - } - - base::FilePath good1_path() { - return data_dir_.AppendASCII("good").AppendASCII("Extensions") - .AppendASCII(good1).AppendASCII("2"); - } - - base::FilePath good2_path() { - return data_dir_.AppendASCII("good").AppendASCII("Extensions") - .AppendASCII(good2).AppendASCII("1.0"); - } - void TestExternalProvider(MockExtensionProvider* provider, Manifest::Location location); @@ -1031,11 +996,10 @@ class ExtensionServiceTest EXPECT_EQ(count, GetPrefKeyCount()); } - testing::AssertionResult ValidateBooleanPref( - const std::string& extension_id, - const std::string& pref_path, - bool expected_val) { - std::string msg = "while checking: "; + void ValidateBooleanPref(const std::string& extension_id, + const std::string& pref_path, + bool expected_val) { + std::string msg = " while checking: "; msg += extension_id; msg += " "; msg += pref_path; @@ -1045,26 +1009,13 @@ class ExtensionServiceTest PrefService* prefs = profile_->GetPrefs(); const DictionaryValue* dict = prefs->GetDictionary("extensions.settings"); - if (!dict) { - return testing::AssertionFailure() - << "extension.settings does not exist " << msg; - } - + ASSERT_TRUE(dict != NULL) << msg; const DictionaryValue* pref = NULL; - if (!dict->GetDictionary(extension_id, &pref)) { - return testing::AssertionFailure() - << "extension pref does not exist " << msg; - } - + ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; + EXPECT_TRUE(pref != NULL) << msg; bool val; - if (!pref->GetBoolean(pref_path, &val)) { - return testing::AssertionFailure() - << pref_path << " pref not found " << msg; - } - - return expected_val == val - ? testing::AssertionSuccess() - : testing::AssertionFailure() << "Value is incorrect " << msg; + ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg; + EXPECT_EQ(expected_val, val) << msg; } bool IsPrefExist(const std::string& extension_id, @@ -1264,7 +1215,16 @@ void PackExtensionTestClient::OnPackFailure(const std::string& error_message, // Test loading good extensions from the profile directory. TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { InitPluginService(); - InitializeGoodInstalledExtensionService(); + + // Initialize the test dir with a good Preferences/extensions. + base::FilePath source_install_dir = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions"); + base::FilePath pref_path = source_install_dir + .DirName() + .AppendASCII("Preferences"); + InitializeInstalledExtensionService(pref_path, source_install_dir); + service_->Init(); uint32 expected_num_extensions = 3u; @@ -1407,7 +1367,15 @@ TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) { // Test loading bad extensions from the profile directory. TEST_F(ExtensionServiceTest, CleanupOnStartup) { InitPluginService(); - InitializeGoodInstalledExtensionService(); + + base::FilePath source_install_dir = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions"); + base::FilePath pref_path = source_install_dir + .DirName() + .AppendASCII("Preferences"); + + InitializeInstalledExtensionService(pref_path, source_install_dir); // Simulate that one of them got partially deleted by clearing its pref. { @@ -1734,12 +1702,12 @@ TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) { const Extension* extension = service_->GetExtensionById(good_crx, false); ASSERT_TRUE(extension); ASSERT_TRUE(extension->from_bookmark()); - ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); + ValidateBooleanPref(good_crx, kPrefFromBookmark, true); // Upgrade to version 2.0, the flag should be preserved. path = data_dir_.AppendASCII("good2.crx"); UpdateExtension(good_crx, path, ENABLED); - ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); + ValidateBooleanPref(good_crx, kPrefFromBookmark, true); extension = service_->GetExtensionById(good_crx, false); ASSERT_TRUE(extension); ASSERT_TRUE(extension->from_bookmark()); @@ -2039,8 +2007,14 @@ TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) { InitializeEmptyExtensionService(); - ASSERT_TRUE(base::PathExists(good1_path())); - const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW); + base::FilePath path = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions") + .AppendASCII(good1) + .AppendASCII("2"); + + ASSERT_TRUE(base::PathExists(path)); + const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW); EXPECT_EQ(0u, GetErrors().size()); EXPECT_EQ(1u, service_->extensions()->size()); ExtensionPrefs* prefs = service_->extension_prefs(); @@ -2762,14 +2736,14 @@ TEST_F(ExtensionServiceTest, FromWebStore) { std::string id = extension->id(); ValidatePrefKeyCount(1); - ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false)); + ValidateBooleanPref(good_crx, "from_webstore", false); ASSERT_FALSE(extension->from_webstore()); // Test install from web store. InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store. ValidatePrefKeyCount(1); - ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true)); + ValidateBooleanPref(good_crx, "from_webstore", true); // Reload so extension gets reinitialized with new value. service_->ReloadExtensions(); @@ -2780,7 +2754,7 @@ TEST_F(ExtensionServiceTest, FromWebStore) { path = data_dir_.AppendASCII("good2.crx"); UpdateExtension(good_crx, path, ENABLED); ValidatePrefKeyCount(1); - ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true)); + ValidateBooleanPref(good_crx, "from_webstore", true); } // Test upgrading a signed extension. @@ -2993,8 +2967,16 @@ TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) { #if !defined(OS_CHROMEOS) // LOAD extensions with plugins require approval. TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) { - base::FilePath extension_with_plugin_path = good1_path(); - base::FilePath extension_no_plugin_path = good2_path(); + base::FilePath extension_with_plugin_path = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions") + .AppendASCII(good1) + .AppendASCII("2"); + base::FilePath extension_no_plugin_path = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions") + .AppendASCII(good2) + .AppendASCII("1.0"); InitPluginService(); InitializeEmptyExtensionService(); @@ -3289,101 +3271,97 @@ TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) { EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId)); } -#if defined(ENABLE_BLACKLIST_TESTS) -// Tests blacklisting then unblacklisting extensions after the service has been -// initialized. +// Test pref settings for blacklist and unblacklist extensions. TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( - new FakeSafeBrowsingDatabaseManager(true)); - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); - - // A profile with 3 extensions installed: good0, good1, and good2. - InitializeGoodInstalledExtensionService(); - service_->Init(); + InitializeEmptyExtensionService(); + std::vector<std::string> blacklist; + blacklist.push_back(good0); + blacklist.push_back("invalid_id"); // an invalid id + blacklist.push_back(good1); + ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist, + "v1"); + + // Make sure pref is updated + base::RunLoop().RunUntilIdle(); - const ExtensionSet* extensions = service_->extensions(); - const ExtensionSet* blacklisted_extensions = - service_->blacklisted_extensions(); + // blacklist is set for good0,1,2 + ValidateBooleanPref(good0, "blacklist", true); + ValidateBooleanPref(good1, "blacklist", true); + // invalid_id should not be inserted to pref. + EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); - EXPECT_TRUE( extensions->Contains(good0) && - !blacklisted_extensions->Contains(good0)); - EXPECT_TRUE( extensions->Contains(good1) && - !blacklisted_extensions->Contains(good1)); - EXPECT_TRUE( extensions->Contains(good2) && - !blacklisted_extensions->Contains(good2)); + // remove good1, add good2 + blacklist.pop_back(); + blacklist.push_back(good2); + ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist, + "v2"); - EXPECT_FALSE(IsPrefExist(good0, "blacklist")); + // only good0 and good1 should be set + ValidateBooleanPref(good0, "blacklist", true); EXPECT_FALSE(IsPrefExist(good1, "blacklist")); - EXPECT_FALSE(IsPrefExist(good2, "blacklist")); + ValidateBooleanPref(good2, "blacklist", true); EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); +} - // Blacklist good0 and good1 (and an invalid extension ID). - blacklist_db->SetUnsafe(good0, good1, "invalid_id").NotifyUpdate(); - base::RunLoop().RunUntilIdle(); +// Unload installed extension from blacklist. +TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) { + InitializeEmptyExtensionService(); - EXPECT_TRUE(!extensions->Contains(good0) && - blacklisted_extensions->Contains(good0)); - EXPECT_TRUE(!extensions->Contains(good1) && - blacklisted_extensions->Contains(good1)); - EXPECT_TRUE( extensions->Contains(good2) && - !blacklisted_extensions->Contains(good2)); + base::FilePath path = data_dir_.AppendASCII("good.crx"); - EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true)); - EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true)); - EXPECT_FALSE(IsPrefExist(good2, "blacklist")); - EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); + const Extension* good = InstallCRX(path, INSTALL_NEW); + EXPECT_EQ(good_crx, good->id()); + UpdateExtension(good_crx, path, FAILED_SILENTLY); - // Un-blacklist good1 and blacklist good2. - blacklist_db->SetUnsafe(good0, good2, "invalid_id").NotifyUpdate(); + std::vector<std::string> blacklist; + blacklist.push_back(good_crx); + ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist, + "v1"); + + // Make sure pref is updated base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(!extensions->Contains(good0) && - blacklisted_extensions->Contains(good0)); - EXPECT_TRUE( extensions->Contains(good1) && - !blacklisted_extensions->Contains(good1)); - EXPECT_TRUE(!extensions->Contains(good2) && - blacklisted_extensions->Contains(good2)); + // Now, the good_crx is blacklisted. + ValidateBooleanPref(good_crx, "blacklist", true); + EXPECT_EQ(0u, service_->extensions()->size()); + + // Remove good_crx from blacklist + blacklist.pop_back(); + ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist, + "v2"); - EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true)); - EXPECT_FALSE(IsPrefExist(good1, "blacklist")); - EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true)); - EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); + // Make sure pref is updated + base::RunLoop().RunUntilIdle(); + // blacklist value should not be set for good_crx + EXPECT_FALSE(IsPrefExist(good_crx, "blacklist")); } -#endif // defined(ENABLE_BLACKLIST_TESTS) -#if defined(ENABLE_BLACKLIST_TESTS) -// Tests trying to install a blacklisted extension. +// Unload installed extension from blacklist. TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( - new FakeSafeBrowsingDatabaseManager(true)); - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); - InitializeEmptyExtensionService(); - service_->Init(); - // After blacklisting good_crx, we cannot install it. - blacklist_db->SetUnsafe(good_crx).NotifyUpdate(); - base::RunLoop().RunUntilIdle(); + // Fake the blacklisting of good_crx by pretending that we get an update + // which includes it. + extensions::Blacklist* blacklist = + ExtensionSystem::Get(profile_.get())->blacklist(); + blacklist->SetFromUpdater(std::vector<std::string>(1, good_crx), "v1"); + + // Now good_crx is blacklisted. + ValidateBooleanPref(good_crx, "blacklist", true); + // We cannot install good_crx. base::FilePath path = data_dir_.AppendASCII("good.crx"); // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't // decide to install this silently. Somebody should fix these tests, all // 6,000 lines of them. Hah! InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT); EXPECT_EQ(0u, service_->extensions()->size()); + ValidateBooleanPref(good_crx, "blacklist", true); } -#endif // defined(ENABLE_BLACKLIST_TESTS) -#if defined(ENABLE_BLACKLIST_TESTS) // Unload blacklisted extension on policy change. TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( - new FakeSafeBrowsingDatabaseManager(true)); - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); - - // A profile with no extensions installed. InitializeEmptyExtensionService(); - base::FilePath path = data_dir_.AppendASCII("good.crx"); const Extension* good = InstallCRX(path, INSTALL_NEW); @@ -3396,77 +3374,57 @@ TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) { whitelist.Append(new base::StringValue(good_crx)); prefs->Set(prefs::kExtensionInstallAllowList, whitelist); - blacklist_db->SetUnsafe(good_crx).NotifyUpdate(); + std::vector<std::string> blacklist; + blacklist.push_back(good_crx); + ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist, + "v1"); + + // Make sure pref is updated base::RunLoop().RunUntilIdle(); // The good_crx is blacklisted and the whitelist doesn't negate it. - ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true)); + ValidateBooleanPref(good_crx, "blacklist", true); EXPECT_EQ(0u, service_->extensions()->size()); } -#endif // defined(ENABLE_BLACKLIST_TESTS) -#if defined(ENABLE_BLACKLIST_TESTS) -// Tests that a blacklisted extension is eventually unloaded on startup, if it -// wasn't already. +// Test loading extensions from the profile directory, except +// blacklisted ones. TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( - new FakeSafeBrowsingDatabaseManager(true)); - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); - - // A profile with 3 extensions installed: good0, good1, and good2. - InitializeGoodInstalledExtensionService(); - - // Blacklist good1 before the service initializes. - blacklist_db->SetUnsafe(good1); + // Initialize the test dir with a good Preferences/extensions. + base::FilePath source_install_dir = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions"); + base::FilePath pref_path = source_install_dir + .DirName() + .AppendASCII("Preferences"); + InitializeInstalledExtensionService(pref_path, source_install_dir); - // Load extensions. - service_->Init(); - ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet + // Blacklist good1. + std::vector<std::string> blacklist; + blacklist.push_back(good1); + ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist, + "v1"); + // Make sure pref is updated base::RunLoop().RunUntilIdle(); - ASSERT_EQ(1u, service_->blacklisted_extensions()->size()); - ASSERT_EQ(2u, service_->extensions()->size()); - - ASSERT_TRUE(service_->extensions()->Contains(good0)); - ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1)); - ASSERT_TRUE(service_->extensions()->Contains(good2)); -} -#endif // defined(ENABLE_BLACKLIST_TESTS) - -#if defined(ENABLE_BLACKLIST_TESTS) -// Tests extensions blacklisted in prefs on startup; one still blacklisted by -// safe browsing, the other not. The not-blacklisted one should recover. -TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( - new FakeSafeBrowsingDatabaseManager(true)); - Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); - - InitializeGoodInstalledExtensionService(); - service_->extension_prefs()->SetExtensionBlacklisted(good0, true); - service_->extension_prefs()->SetExtensionBlacklisted(good1, true); - blacklist_db->SetUnsafe(good1); + ValidateBooleanPref(good1, "blacklist", true); + // Load extensions. service_->Init(); - ASSERT_EQ(2u, service_->blacklisted_extensions()->size()); - ASSERT_EQ(1u, service_->extensions()->size()); - - ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good0)); - ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1)); - ASSERT_TRUE(service_->extensions()->Contains(good2)); - - // Give time for the blacklist to update. - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(1u, service_->blacklisted_extensions()->size()); - ASSERT_EQ(2u, service_->extensions()->size()); + std::vector<string16> errors = GetErrors(); + for (std::vector<string16>::iterator err = errors.begin(); + err != errors.end(); ++err) { + LOG(ERROR) << *err; + } + ASSERT_EQ(2u, loaded_.size()); - ASSERT_TRUE(service_->extensions()->Contains(good0)); - ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1)); - ASSERT_TRUE(service_->extensions()->Contains(good2)); + EXPECT_TRUE(service_->GetInstalledExtension(good1)); + int include_mask = ExtensionService::INCLUDE_EVERYTHING & + ~ExtensionService::INCLUDE_BLACKLISTED; + EXPECT_FALSE(service_->GetExtensionById(good1, include_mask)); } -#endif // defined(ENABLE_BLACKLIST_TESTS) // Will not install extension blacklisted by policy. TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) { @@ -5164,10 +5122,15 @@ TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) { &triggered_type)); // Safe due to WeakPtrFactory scope. // Install a component extension. + base::FilePath path = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions") + .AppendASCII(good0) + .AppendASCII("1.0.0.0"); std::string manifest; ASSERT_TRUE(base::ReadFileToString( - good0_path().Append(extensions::kManifestFilename), &manifest)); - service_->component_loader()->Add(manifest, good0_path()); + path.Append(extensions::kManifestFilename), &manifest)); + service_->component_loader()->Add(manifest, path); ASSERT_FALSE(service_->is_ready()); service_->Init(); ASSERT_TRUE(service_->is_ready()); @@ -5178,7 +5141,14 @@ TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) { } TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) { - InitializeGoodInstalledExtensionService(); + // Initialize the test dir with a good Preferences/extensions. + base::FilePath source_install_dir = data_dir_ + .AppendASCII("good") + .AppendASCII("Extensions"); + base::FilePath pref_path = source_install_dir + .DirName() + .AppendASCII("Preferences"); + InitializeInstalledExtensionService(pref_path, source_install_dir); bool flare_was_called = false; syncer::ModelType triggered_type(syncer::UNSPECIFIED); diff --git a/chrome/browser/extensions/extension_service_unittest.h b/chrome/browser/extensions/extension_service_unittest.h index 05b71a08..4239714 100644 --- a/chrome/browser/extensions/extension_service_unittest.h +++ b/chrome/browser/extensions/extension_service_unittest.h @@ -49,8 +49,6 @@ class ExtensionServiceTestBase : public testing::Test { const base::FilePath& prefs_file, const base::FilePath& source_install_dir); - void InitializeGoodInstalledExtensionService(); - void InitializeEmptyExtensionService(); void InitializeExtensionProcessManager(); diff --git a/chrome/browser/extensions/fake_safe_browsing_database_manager.cc b/chrome/browser/extensions/fake_safe_browsing_database_manager.cc index 714a3fa..6abb86e 100644 --- a/chrome/browser/extensions/fake_safe_browsing_database_manager.cc +++ b/chrome/browser/extensions/fake_safe_browsing_database_manager.cc @@ -16,51 +16,15 @@ namespace extensions { -FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager(bool enabled) +FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager() : SafeBrowsingDatabaseManager( make_scoped_refptr(SafeBrowsingService::CreateSafeBrowsingService())), - enabled_(enabled) { + enabled_(false) { } FakeSafeBrowsingDatabaseManager::~FakeSafeBrowsingDatabaseManager() { } -FakeSafeBrowsingDatabaseManager& FakeSafeBrowsingDatabaseManager::Enable() { - enabled_ = true; - return *this; -} - -FakeSafeBrowsingDatabaseManager& -FakeSafeBrowsingDatabaseManager::ClearUnsafe() { - unsafe_ids_.clear(); - return *this; -} - -FakeSafeBrowsingDatabaseManager& FakeSafeBrowsingDatabaseManager::SetUnsafe( - const std::string& a) { - ClearUnsafe(); - unsafe_ids_.insert(a); - return *this; -} - -FakeSafeBrowsingDatabaseManager& FakeSafeBrowsingDatabaseManager::SetUnsafe( - const std::string& a, const std::string& b) { - SetUnsafe(a); - unsafe_ids_.insert(b); - return *this; -} - -FakeSafeBrowsingDatabaseManager& FakeSafeBrowsingDatabaseManager::SetUnsafe( - const std::string& a, const std::string& b, const std::string& c) { - SetUnsafe(a, b); - unsafe_ids_.insert(c); - return *this; -} - -void FakeSafeBrowsingDatabaseManager::NotifyUpdate() { - SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished(true); -} - bool FakeSafeBrowsingDatabaseManager::CheckExtensionIDs( const std::set<std::string>& extension_ids, Client* client) { diff --git a/chrome/browser/extensions/fake_safe_browsing_database_manager.h b/chrome/browser/extensions/fake_safe_browsing_database_manager.h index d6b8e37..2a91b73 100644 --- a/chrome/browser/extensions/fake_safe_browsing_database_manager.h +++ b/chrome/browser/extensions/fake_safe_browsing_database_manager.h @@ -18,7 +18,7 @@ namespace extensions { // call set_enabled to enable it. class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { public: - explicit FakeSafeBrowsingDatabaseManager(bool enabled); + FakeSafeBrowsingDatabaseManager(); // Returns true if synchronously safe, false if not in which case the unsafe // IDs taken from |unsafe_ids_| are passed to to |client| on the current @@ -26,18 +26,11 @@ class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { virtual bool CheckExtensionIDs(const std::set<std::string>& extension_ids, Client* client) OVERRIDE; - // Return |this| to chain together SetUnsafe(...).NotifyUpdate() conveniently. - FakeSafeBrowsingDatabaseManager& Enable(); - FakeSafeBrowsingDatabaseManager& ClearUnsafe(); - FakeSafeBrowsingDatabaseManager& SetUnsafe(const std::string& a); - FakeSafeBrowsingDatabaseManager& SetUnsafe(const std::string& a, - const std::string& b); - FakeSafeBrowsingDatabaseManager& SetUnsafe(const std::string& a, - const std::string& b, - const std::string& c); - - // Send the update notification. - void NotifyUpdate(); + void set_enabled(bool enabled) { enabled_ = enabled; } + + void set_unsafe_ids(const std::set<std::string>& unsafe_ids) { + unsafe_ids_ = unsafe_ids; + } private: virtual ~FakeSafeBrowsingDatabaseManager(); diff --git a/chrome/browser/extensions/updater/extension_downloader.cc b/chrome/browser/extensions/updater/extension_downloader.cc index a76e3c7..0c114f7 100644 --- a/chrome/browser/extensions/updater/extension_downloader.cc +++ b/chrome/browser/extensions/updater/extension_downloader.cc @@ -719,13 +719,23 @@ void ExtensionDownloader::OnCRXFetchComplete( (response_code == 200 || url.SchemeIsFile())) { RETRY_HISTOGRAM("CrxFetchSuccess", extensions_queue_.active_request_failure_count(), url); - base::FilePath crx_path; - // Take ownership of the file at |crx_path|. - CHECK(source->GetResponseAsFilePath(true, &crx_path)); - RecordCRXWriteHistogram(true, crx_path); - delegate_->OnExtensionDownloadFinished( - id, crx_path, url, extensions_queue_.active_request()->version, - ping, request_ids); + if (id == kBlacklistAppID) { + std::string data; + source->GetResponseAsString(&data); + // TODO(asargent): try to get rid of this special case for the blacklist + // to simplify the delegate's interface. + delegate_->OnBlacklistDownloadFinished( + data, extensions_queue_.active_request()->package_hash, + extensions_queue_.active_request()->version, ping, request_ids); + } else { + base::FilePath crx_path; + // Take ownership of the file at |crx_path|. + CHECK(source->GetResponseAsFilePath(true, &crx_path)); + RecordCRXWriteHistogram(true, crx_path); + delegate_->OnExtensionDownloadFinished( + id, crx_path, url, extensions_queue_.active_request()->version, + ping, request_ids); + } } else { VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec() << "' response code:" << response_code; diff --git a/chrome/browser/extensions/updater/extension_downloader_delegate.h b/chrome/browser/extensions/updater/extension_downloader_delegate.h index acc239b..99f5d6e 100644 --- a/chrome/browser/extensions/updater/extension_downloader_delegate.h +++ b/chrome/browser/extensions/updater/extension_downloader_delegate.h @@ -89,6 +89,15 @@ class ExtensionDownloaderDelegate { const PingResult& ping_result, const std::set<int>& request_ids) = 0; + // Same as OnExtensionDownloadFinished() but only for the kBlacklistAppID + // extension, which passes different data to the delegate. + virtual void OnBlacklistDownloadFinished( + const std::string& data, + const std::string& package_hash, + const std::string& version, + const PingResult& ping_result, + const std::set<int>& request_ids) = 0; + // The remaining methods are used by the ExtensionDownloader to retrieve // information about extensions from the delegate. diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc index 0429ec1..6b9cece 100644 --- a/chrome/browser/extensions/updater/extension_updater.cc +++ b/chrome/browser/extensions/updater/extension_updater.cc @@ -18,6 +18,7 @@ #include "base/strings/string_split.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/api/module/module.h" +#include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/pending_extension_manager.h" @@ -38,6 +39,7 @@ using base::RandInt; using base::Time; using base::TimeDelta; using content::BrowserThread; +using prefs::kExtensionBlacklistUpdateVersion; using prefs::kLastExtensionsUpdateCheck; using prefs::kNextExtensionsUpdateCheck; @@ -91,7 +93,7 @@ int CalculateActivePingDays(const Time& last_active_ping_day, namespace extensions { ExtensionUpdater::CheckParams::CheckParams() - : install_immediately(false) {} + : check_blacklist(true), install_immediately(false) {} ExtensionUpdater::CheckParams::~CheckParams() {} @@ -129,12 +131,13 @@ ExtensionUpdater::ExtensionUpdater(ExtensionServiceInterface* service, ExtensionPrefs* extension_prefs, PrefService* prefs, Profile* profile, + Blacklist* blacklist, int frequency_seconds) : alive_(false), weak_ptr_factory_(this), service_(service), frequency_seconds_(frequency_seconds), will_check_soon_(false), extension_prefs_(extension_prefs), - prefs_(prefs), profile_(profile), + prefs_(prefs), profile_(profile), blacklist_(blacklist), next_request_id_(0), crx_install_is_running_(false) { DCHECK_GE(frequency_seconds_, 5); @@ -371,6 +374,17 @@ void ExtensionUpdater::CheckNow(const CheckParams& params) { } } + // Start a fetch of the blacklist if needed. + if (params.check_blacklist) { + ManifestFetchData::PingData ping_data; + ping_data.rollcall_days = + CalculatePingDays(extension_prefs_->BlacklistLastPingDay()); + request.in_progress_ids_.push_back(ExtensionDownloader::kBlacklistAppID); + downloader_->StartBlacklistUpdate( + prefs_->GetString(kExtensionBlacklistUpdateVersion), ping_data, + request_id); + } + // StartAllPending() might call OnExtensionDownloadFailed/Finished before // it returns, which would cause NotifyIfFinished to incorrectly try to // send out a notification. So check before we call StartAllPending if any @@ -421,6 +435,7 @@ bool ExtensionUpdater::CheckExtensionSoon(const std::string& extension_id, CheckParams params; params.ids.push_back(extension_id); + params.check_blacklist = false; params.callback = base::Bind(&ExtensionUpdater::ExtensionCheckFinished, weak_ptr_factory_.GetWeakPtr(), extension_id, callback); @@ -483,6 +498,38 @@ void ExtensionUpdater::OnExtensionDownloadFinished( MaybeInstallCRXFile(); } +void ExtensionUpdater::OnBlacklistDownloadFinished( + const std::string& data, + const std::string& package_hash, + const std::string& version, + const PingResult& ping, + const std::set<int>& request_ids) { + DCHECK(alive_); + UpdatePingData(ExtensionDownloader::kBlacklistAppID, ping); + for (std::set<int>::const_iterator it = request_ids.begin(); + it != request_ids.end(); ++it) { + InProgressCheck& request = requests_in_progress_[*it]; + request.in_progress_ids_.remove(ExtensionDownloader::kBlacklistAppID); + NotifyIfFinished(*it); + } + + // Verify sha256 hash value. + char sha256_hash_value[crypto::kSHA256Length]; + crypto::SHA256HashString(data, sha256_hash_value, crypto::kSHA256Length); + std::string hash_in_hex = base::HexEncode(sha256_hash_value, + crypto::kSHA256Length); + + if (package_hash != hash_in_hex) { + NOTREACHED() << "Fetched blacklist checksum is not as expected. " + << "Expected: " << package_hash << " Actual: " << hash_in_hex; + return; + } + std::vector<std::string> blacklist; + base::SplitString(data, '\n', &blacklist); + + blacklist_->SetFromUpdater(blacklist, version); +} + bool ExtensionUpdater::GetPingDataForExtension( const std::string& id, ManifestFetchData::PingData* ping_data) { @@ -509,6 +556,10 @@ bool ExtensionUpdater::IsExtensionPending(const std::string& id) { bool ExtensionUpdater::GetExtensionExistingVersion(const std::string& id, std::string* version) { DCHECK(alive_); + if (id == ExtensionDownloader::kBlacklistAppID) { + *version = prefs_->GetString(kExtensionBlacklistUpdateVersion); + return true; + } const Extension* extension = service_->GetExtensionById(id, true); if (!extension) return false; @@ -523,8 +574,13 @@ bool ExtensionUpdater::GetExtensionExistingVersion(const std::string& id, void ExtensionUpdater::UpdatePingData(const std::string& id, const PingResult& ping_result) { DCHECK(alive_); - if (ping_result.did_ping) - extension_prefs_->SetLastPingDay(id, ping_result.day_start); + if (ping_result.did_ping) { + if (id == ExtensionDownloader::kBlacklistAppID) { + extension_prefs_->SetBlacklistLastPingDay(ping_result.day_start); + } else if (service_->GetExtensionById(id, true) != NULL) { + extension_prefs_->SetLastPingDay(id, ping_result.day_start); + } + } if (extension_prefs_->GetActiveBit(id)) { extension_prefs_->SetActiveBit(id, false); extension_prefs_->SetLastActivePingDay(id, ping_result.day_start); diff --git a/chrome/browser/extensions/updater/extension_updater.h b/chrome/browser/extensions/updater/extension_updater.h index b178aec..3a40f7e 100644 --- a/chrome/browser/extensions/updater/extension_updater.h +++ b/chrome/browser/extensions/updater/extension_updater.h @@ -32,6 +32,7 @@ class Profile; namespace extensions { +class Blacklist; class ExtensionDownloader; class ExtensionPrefs; class ExtensionUpdaterTest; @@ -52,7 +53,8 @@ class ExtensionUpdater : public ExtensionDownloaderDelegate, typedef base::Closure FinishedCallback; struct CheckParams { - // Creates a default CheckParams instance that checks for all extensions. + // Creates a default CheckParams instance that checks for all extensions and + // the extension blacklist. CheckParams(); ~CheckParams(); @@ -60,6 +62,9 @@ class ExtensionUpdater : public ExtensionDownloaderDelegate, // all extensions will be included in the update check. std::list<std::string> ids; + // If true, the extension blacklist will also be updated. + bool check_blacklist; + // Normally extension updates get installed only when the extension is idle. // Setting this to true causes any updates that are found to be installed // right away. @@ -77,6 +82,7 @@ class ExtensionUpdater : public ExtensionDownloaderDelegate, ExtensionPrefs* extension_prefs, PrefService* prefs, Profile* profile, + Blacklist* blacklist, int frequency_seconds); virtual ~ExtensionUpdater(); @@ -181,6 +187,13 @@ class ExtensionUpdater : public ExtensionDownloaderDelegate, const PingResult& ping, const std::set<int>& request_id) OVERRIDE; + virtual void OnBlacklistDownloadFinished( + const std::string& data, + const std::string& package_hash, + const std::string& version, + const PingResult& ping, + const std::set<int>& request_id) OVERRIDE; + virtual bool GetPingDataForExtension( const std::string& id, ManifestFetchData::PingData* ping_data) OVERRIDE; @@ -229,6 +242,7 @@ class ExtensionUpdater : public ExtensionDownloaderDelegate, ExtensionPrefs* extension_prefs_; PrefService* prefs_; Profile* profile_; + Blacklist* blacklist_; std::map<int, InProgressCheck> requests_in_progress_; int next_request_id_; diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc index cc5d412..7fc96f4 100644 --- a/chrome/browser/extensions/updater/extension_updater_unittest.cc +++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc @@ -24,10 +24,12 @@ #include "base/threading/thread.h" #include "base/version.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_sync_data.h" #include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/extensions/test_blacklist.h" #include "chrome/browser/extensions/test_extension_prefs.h" #include "chrome/browser/extensions/test_extension_service.h" #include "chrome/browser/extensions/test_extension_system.h" @@ -132,6 +134,11 @@ class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate { const std::string&, const PingResult&, const std::set<int>&)); + MOCK_METHOD5(OnBlacklistDownloadFinished, void(const std::string&, + const std::string&, + const std::string&, + const PingResult&, + const std::set<int>&)); MOCK_METHOD2(GetPingDataForExtension, bool(const std::string&, ManifestFetchData::PingData*)); MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&)); @@ -229,7 +236,9 @@ class NotificationsObserver : public content::NotificationObserver { class MockService : public TestExtensionService { public: explicit MockService(TestExtensionPrefs* prefs) - : prefs_(prefs), pending_extension_manager_(*this) { + : prefs_(prefs), + pending_extension_manager_(*this), + blacklist_(prefs_->prefs()) { } virtual ~MockService() {} @@ -250,6 +259,8 @@ class MockService : public TestExtensionService { PrefService* pref_service() { return prefs_->pref_service(); } + Blacklist* blacklist() { return &blacklist_; } + // Creates test extensions and inserts them into list. The name and // version are all based on their index. If |update_url| is non-null, it // will be used as the update_url for each extension. @@ -277,6 +288,7 @@ class MockService : public TestExtensionService { TestExtensionPrefs* const prefs_; PendingExtensionManager pending_extension_manager_; TestingProfile profile_; + Blacklist blacklist_; private: DISALLOW_COPY_AND_ASSIGN(MockService); @@ -563,8 +575,13 @@ class ExtensionUpdaterTest : public testing::Test { net::TestURLFetcherFactory factory; ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), - service.profile(), 60*60*24); + service.profile(), service.blacklist(), 60*60*24); updater.Start(); + // Disable blacklist checks (tested elsewhere) so that we only see the + // update HTTP request. + ExtensionUpdater::CheckParams check_params; + check_params.check_blacklist = false; + updater.set_default_check_params(check_params); // Tell the update that it's time to do update checks. EXPECT_EQ(0u, observer.StartedCount()); @@ -596,6 +613,45 @@ class ExtensionUpdaterTest : public testing::Test { EXPECT_EQ("", params["uc"]); } + void TestBlacklistUpdateCheckRequests() { + // Setup and start the updater. + ServiceForManifestTests service(prefs_.get()); + NotificationsObserver observer; + + net::TestURLFetcherFactory factory; + ExtensionUpdater updater( + &service, service.extension_prefs(), service.pref_service(), + service.profile(), service.blacklist(), 60*60*24); + updater.Start(); + + // Tell the updater that it's time to do update checks. + EXPECT_EQ(0u, observer.StartedCount()); + SimulateTimerFired(&updater); + EXPECT_EQ(1u, observer.StartedCount()); + + // Get the url our mock fetcher was asked to fetch. + net::TestURLFetcher* fetcher = + factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); + ASSERT_FALSE(fetcher == NULL); + const GURL& url = fetcher->GetOriginalURL(); + + EXPECT_FALSE(url.is_empty()); + EXPECT_TRUE(url.is_valid()); + EXPECT_TRUE(url.SchemeIs("https")); + EXPECT_EQ("clients2.google.com", url.host()); + EXPECT_EQ("/service/update2/crx", url.path()); + + // Validate the extension request parameters in the query. It should + // look something like "x=id%3D<id>%26v%3D<version>%26uc". + EXPECT_TRUE(url.has_query()); + std::map<std::string, std::string> params; + VerifyQueryAndExtractParameters(url.query(), ¶ms); + EXPECT_EQ("com.google.crx.blacklist", params["id"]); + EXPECT_EQ("0", params["v"]); + EXPECT_EQ("", params["uc"]); + EXPECT_TRUE(ContainsKey(params, "ping")); + } + void TestUpdateUrlDataEmpty() { const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; const std::string version = "1.0"; @@ -972,6 +1028,7 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater(service.get(), service->extension_prefs(), service->pref_service(), service->profile(), + service->blacklist(), kUpdateFrequencySecs); updater.Start(); ResetDownloader( @@ -1041,6 +1098,58 @@ class ExtensionUpdaterTest : public testing::Test { EXPECT_EQ(extension_file_path, tmpfile_path); } + void TestBlacklistDownloading() { + net::TestURLFetcherFactory factory; + net::TestURLFetcher* fetcher = NULL; + MockService service(prefs_.get()); + TestBlacklist blacklist(service.blacklist()); + ExtensionUpdater updater( + &service, service.extension_prefs(), service.pref_service(), + service.profile(), blacklist.blacklist(), kUpdateFrequencySecs); + updater.Start(); + ResetDownloader( + &updater, + new ExtensionDownloader(&updater, service.request_context())); + updater.downloader_->extensions_queue_.set_backoff_policy( + &kNoBackoffPolicy); + + GURL test_url("http://localhost/extension.crx"); + + std::string id = "com.google.crx.blacklist"; + + std::string hash = + "CCEA231D3CD30A348DA1383ED311EAC11E82360773CB2BA4E2C3A5FF16E337CC"; + + std::string version = "0.0.1"; + std::set<int> requests; + requests.insert(0); + scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch( + new ExtensionDownloader::ExtensionFetch( + id, test_url, hash, version, requests)); + updater.downloader_->FetchUpdatedExtension(fetch.Pass()); + + // Call back the ExtensionUpdater with a 200 response and some test data. + std::string extension_data("aaaabbbbcccceeeeaaaabbbbcccceeee"); + EXPECT_FALSE(blacklist.IsBlacklisted(extension_data)); + + fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId); + EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); + EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags); + + fetcher->set_url(test_url); + fetcher->set_status(net::URLRequestStatus()); + fetcher->set_response_code(200); + fetcher->SetResponseString(extension_data); + fetcher->delegate()->OnURLFetchComplete(fetcher); + + RunUntilIdle(); + + EXPECT_TRUE(blacklist.IsBlacklisted(extension_data)); + + EXPECT_EQ(version, service.pref_service()-> + GetString(prefs::kExtensionBlacklistUpdateVersion)); + } + // Two extensions are updated. If |updates_start_running| is true, the // mock extensions service has UpdateExtension(...) return true, and // the test is responsible for creating fake CrxInstallers. Otherwise, @@ -1051,7 +1160,7 @@ class ExtensionUpdaterTest : public testing::Test { ServiceForDownloadTests service(prefs_.get()); ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), - service.profile(), kUpdateFrequencySecs); + service.profile(), service.blacklist(), kUpdateFrequencySecs); updater.Start(); ResetDownloader( &updater, @@ -1265,8 +1374,9 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), - service.profile(), kUpdateFrequencySecs); + service.profile(), service.blacklist(), kUpdateFrequencySecs); ExtensionUpdater::CheckParams params; + params.check_blacklist = false; updater.Start(); updater.CheckNow(params); @@ -1358,7 +1468,7 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), - service.profile(), kUpdateFrequencySecs); + service.profile(), service.blacklist(), kUpdateFrequencySecs); updater.Start(); ResetDownloader( &updater, @@ -1407,6 +1517,10 @@ TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) { TestExtensionUpdateCheckRequests(true); } +TEST_F(ExtensionUpdaterTest, TestBlacklistUpdateCheckRequests) { + TestBlacklistUpdateCheckRequests(); +} + TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) { TestUpdateUrlDataEmpty(); TestUpdateUrlDataSimple(); @@ -1447,6 +1561,10 @@ TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) { TestSingleExtensionDownloading(true, true); } +TEST_F(ExtensionUpdaterTest, TestBlacklistDownloading) { + TestBlacklistDownloading(); +} + TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) { TestMultipleExtensionDownloading(false); } @@ -1475,7 +1593,7 @@ TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) { ServiceForManifestTests service(prefs_.get()); ExtensionUpdater updater(&service, service.extension_prefs(), service.pref_service(), service.profile(), - kUpdateFrequencySecs); + service.blacklist(), kUpdateFrequencySecs); MockExtensionDownloaderDelegate delegate; // Set the downloader directly, so that all its events end up in the mock // |delegate|. @@ -1498,6 +1616,7 @@ TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) { service.set_extensions(extensions); ExtensionUpdater::CheckParams params; + params.check_blacklist = false; updater.Start(); updater.CheckNow(params); } @@ -1507,7 +1626,7 @@ TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) { ServiceForManifestTests service(prefs_.get()); ExtensionUpdater updater(&service, service.extension_prefs(), service.pref_service(), service.profile(), - kUpdateFrequencySecs); + service.blacklist(), kUpdateFrequencySecs); MockExtensionDownloaderDelegate delegate; // Set the downloader directly, so that all its events end up in the mock // |delegate|. @@ -1536,6 +1655,7 @@ TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) { service.set_extensions(enabled_extensions); service.set_disabled_extensions(disabled_extensions); ExtensionUpdater::CheckParams params; + params.check_blacklist = false; updater.Start(); updater.CheckNow(params); } @@ -1613,7 +1733,7 @@ TEST_F(ExtensionUpdaterTest, TestCheckSoon) { net::TestURLFetcherFactory factory; ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), - service.profile(), kUpdateFrequencySecs); + service.profile(), service.blacklist(), kUpdateFrequencySecs); EXPECT_FALSE(updater.WillCheckSoon()); updater.Start(); EXPECT_FALSE(updater.WillCheckSoon()); diff --git a/chrome/browser/safe_browsing/database_manager.cc b/chrome/browser/safe_browsing/database_manager.cc index 5e3522d..fa4c296 100644 --- a/chrome/browser/safe_browsing/database_manager.cc +++ b/chrome/browser/safe_browsing/database_manager.cc @@ -521,14 +521,6 @@ void SafeBrowsingDatabaseManager::StopOnIOThread(bool shutdown) { } } -void SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished( - bool update_succeeded) { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, - content::Source<SafeBrowsingDatabaseManager>(this), - content::Details<bool>(&update_succeeded)); -} - SafeBrowsingDatabaseManager::QueuedCheck::QueuedCheck( const safe_browsing_util::ListType check_type, Client* client, @@ -867,6 +859,14 @@ void SafeBrowsingDatabaseManager::DatabaseUpdateFinished( this, update_succeeded)); } +void SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished( + bool update_succeeded) { + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, + content::Source<SafeBrowsingDatabaseManager>(this), + content::Details<bool>(&update_succeeded)); +} + void SafeBrowsingDatabaseManager::OnCloseDatabase() { DCHECK_EQ(base::MessageLoop::current(), safe_browsing_thread_->message_loop()); diff --git a/chrome/browser/safe_browsing/database_manager.h b/chrome/browser/safe_browsing/database_manager.h index ed17f5a..25b7f5a 100644 --- a/chrome/browser/safe_browsing/database_manager.h +++ b/chrome/browser/safe_browsing/database_manager.h @@ -210,9 +210,6 @@ class SafeBrowsingDatabaseManager protected: virtual ~SafeBrowsingDatabaseManager(); - // protected for tests. - void NotifyDatabaseUpdateFinished(bool update_succeeded); - private: friend class base::RefCountedThreadSafe<SafeBrowsingDatabaseManager>; friend class SafeBrowsingServerTest; @@ -298,6 +295,8 @@ class SafeBrowsingDatabaseManager void DatabaseUpdateFinished(bool update_succeeded); + void NotifyDatabaseUpdateFinished(bool update_succeeded); + // Called on the db thread to close the database. See CloseDatabase(). void OnCloseDatabase(); diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 8f9fe12..06d5696 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1120,6 +1120,7 @@ 'browser/extensions/extension_apitest.cc', 'browser/extensions/extension_apitest.h', 'browser/extensions/extension_bindings_apitest.cc', + 'browser/extensions/extension_blacklist_browsertest.cc', 'browser/extensions/extension_browsertest.cc', 'browser/extensions/extension_browsertest.h', 'browser/extensions/extension_context_menu_browsertest.cc', diff --git a/tools/lsan/suppressions.txt b/tools/lsan/suppressions.txt index 7473d4a..d38d981 100644 --- a/tools/lsan/suppressions.txt +++ b/tools/lsan/suppressions.txt @@ -58,8 +58,3 @@ leak:StatusIconGtk::UpdatePlatformContextMenu leak:GlobalMenuBar::GlobalMenuBar leak:BookmarkBubbleGtk::InitFolderComboModel leak:TranslateInfoBarBase::CreateLanguageCombobox - -# Leak in BlacklistTest.* http://crbug.com/296828 -leak:BlacklistTest_ClearsPreferencesBlacklistTest::TestBody -leak:BlacklistTest_OnlyIncludesRequestedIDsTest::TestBody -leak:BlacklistTest_SafeBrowsing::TestBody |