summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-23 10:58:42 +0000
committermkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-23 10:58:42 +0000
commit1747eac07a8a2b42f1879be727e686d238f2e363 (patch)
treee98a074cef8eff8e16943f6e2eac0fe09f9ce357
parent237781df23071813168d4906fd85739e2b70e3ee (diff)
downloadchromium_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
-rw-r--r--chrome/browser/chromeos/extensions/external_cache.cc9
-rw-r--r--chrome/browser/chromeos/extensions/external_cache.h7
-rw-r--r--chrome/browser/extensions/api/management/management_browsertest.cc10
-rw-r--r--chrome/browser/extensions/blacklist.cc94
-rw-r--r--chrome/browser/extensions/blacklist.h19
-rw-r--r--chrome/browser/extensions/blacklist_unittest.cc278
-rw-r--r--chrome/browser/extensions/crx_installer_browsertest.cc11
-rw-r--r--chrome/browser/extensions/extension_blacklist_browsertest.cc265
-rw-r--r--chrome/browser/extensions/extension_disabled_ui_browsertest.cc1
-rw-r--r--chrome/browser/extensions/extension_service.cc32
-rw-r--r--chrome/browser/extensions/extension_service.h3
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc354
-rw-r--r--chrome/browser/extensions/extension_service_unittest.h2
-rw-r--r--chrome/browser/extensions/fake_safe_browsing_database_manager.cc40
-rw-r--r--chrome/browser/extensions/fake_safe_browsing_database_manager.h19
-rw-r--r--chrome/browser/extensions/updater/extension_downloader.cc24
-rw-r--r--chrome/browser/extensions/updater/extension_downloader_delegate.h9
-rw-r--r--chrome/browser/extensions/updater/extension_updater.cc64
-rw-r--r--chrome/browser/extensions/updater/extension_updater.h16
-rw-r--r--chrome/browser/extensions/updater/extension_updater_unittest.cc136
-rw-r--r--chrome/browser/safe_browsing/database_manager.cc16
-rw-r--r--chrome/browser/safe_browsing/database_manager.h5
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--tools/lsan/suppressions.txt5
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(&notification_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(&notification_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(), &params);
+ 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