Commit bfa83bbb authored by Jialiu Lin's avatar Jialiu Lin Committed by Commit Bot

Avoid accessing PrefService from PasswordReuseDetector

Previous implementation queries PrefService in
PasswordReuseDetector::CheckNonGaiaEnterprisePasswordReuse(..). However,
CheckNonGaiaEnterprisePasswordReuse(..) is called in a backgroud sequence,
which violates the valid sequence check in PrefService. In other words,
PrefService can NOT be called on background thread. Otherwise, it
will causes crashing.
This CL changes the implementation by propagating enterprise URLs to
PasswordReuseDetector when PasswordStore is initialized to avoid accessing
PrefService from PasswordReuseDetector.

Bug: 852138
Change-Id: I8556f259e6c0e4a7eee077e70db142739336ed67
Reviewed-on: https://chromium-review.googlesource.com/1107247
Commit-Queue: Jialiu Lin <jialiul@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569358}
parent 17ad38cd
...@@ -190,6 +190,16 @@ ChromePasswordProtectionService::ChromePasswordProtectionService( ...@@ -190,6 +190,16 @@ ChromePasswordProtectionService::ChromePasswordProtectionService(
base::BindRepeating( base::BindRepeating(
&ChromePasswordProtectionService::OnWarningTriggerChanged, &ChromePasswordProtectionService::OnWarningTriggerChanged,
base::Unretained(this))); base::Unretained(this)));
pref_change_registrar_->Add(
prefs::kPasswordProtectionLoginURLs,
base::BindRepeating(
&ChromePasswordProtectionService::OnEnterprisePasswordUrlChanged,
base::Unretained(this)));
pref_change_registrar_->Add(
prefs::kPasswordProtectionChangePasswordURL,
base::BindRepeating(
&ChromePasswordProtectionService::OnEnterprisePasswordUrlChanged,
base::Unretained(this)));
password_manager::HashPasswordManager hash_password_manager; password_manager::HashPasswordManager hash_password_manager;
hash_password_manager.set_prefs(profile->GetPrefs()); hash_password_manager.set_prefs(profile->GetPrefs());
base::Optional<password_manager::PasswordHashData> sync_hash_data = base::Optional<password_manager::PasswordHashData> sync_hash_data =
...@@ -1190,4 +1200,10 @@ void ChromePasswordProtectionService::OnWarningTriggerChanged() { ...@@ -1190,4 +1200,10 @@ void ChromePasswordProtectionService::OnWarningTriggerChanged() {
->SchedulePasswordHashUpdate(/*should_log_metrics*/ false); ->SchedulePasswordHashUpdate(/*should_log_metrics*/ false);
} }
void ChromePasswordProtectionService::OnEnterprisePasswordUrlChanged() {
PasswordStoreFactory::GetForProfile(profile_,
ServiceAccessType::EXPLICIT_ACCESS)
->ScheduleEnterprisePasswordURLUpdate();
}
} // namespace safe_browsing } // namespace safe_browsing
...@@ -339,6 +339,10 @@ class ChromePasswordProtectionService : public PasswordProtectionService { ...@@ -339,6 +339,10 @@ class ChromePasswordProtectionService : public PasswordProtectionService {
// enterprise password hashes. // enterprise password hashes.
void OnWarningTriggerChanged(); void OnWarningTriggerChanged();
// Informs PasswordReuseDetector that enterprise password URLs (login URL or
// change password URL) have been changed.
void OnEnterprisePasswordUrlChanged();
scoped_refptr<SafeBrowsingUIManager> ui_manager_; scoped_refptr<SafeBrowsingUIManager> ui_manager_;
TriggerManager* trigger_manager_; TriggerManager* trigger_manager_;
// Profile associated with this instance. // Profile associated with this instance.
......
...@@ -213,18 +213,12 @@ static_library("browser") { ...@@ -213,18 +213,12 @@ static_library("browser") {
"//url", "//url",
] ]
if (password_reuse_detection_support) {
deps += [
"//components/safe_browsing:features",
"//components/safe_browsing/common:safe_browsing_prefs",
]
}
if (!is_ios) { if (!is_ios) {
sources += [ sources += [
"hsts_query.cc", "hsts_query.cc",
"hsts_query.h", "hsts_query.h",
] ]
deps += [ "//components/safe_browsing/common:safe_browsing_prefs" ]
} }
if (is_posix && !is_mac && !is_ios) { if (is_posix && !is_mac && !is_ios) {
......
...@@ -68,7 +68,7 @@ bool ReverseStringLess::operator()(const base::string16& lhs, ...@@ -68,7 +68,7 @@ bool ReverseStringLess::operator()(const base::string16& lhs,
rhs.rend()); rhs.rend());
} }
PasswordReuseDetector::PasswordReuseDetector() : prefs_(nullptr) {} PasswordReuseDetector::PasswordReuseDetector() {}
PasswordReuseDetector::~PasswordReuseDetector() {} PasswordReuseDetector::~PasswordReuseDetector() {}
...@@ -160,10 +160,9 @@ PasswordReuseDetector::CheckNonGaiaEnterprisePasswordReuse( ...@@ -160,10 +160,9 @@ PasswordReuseDetector::CheckNonGaiaEnterprisePasswordReuse(
// Skips password reuse check if |domain| matches enterprise login URL or // Skips password reuse check if |domain| matches enterprise login URL or
// enterprise change password URL. // enterprise change password URL.
GURL page_url(domain); GURL page_url(domain);
if (!prefs_ || if (enterprise_password_urls_.has_value() &&
safe_browsing::MatchesPasswordProtectionLoginURL(page_url, *prefs_) || safe_browsing::MatchesURLList(page_url,
safe_browsing::MatchesPasswordProtectionChangePasswordURL(page_url, enterprise_password_urls_.value())) {
*prefs_)) {
return base::nullopt; return base::nullopt;
} }
...@@ -228,6 +227,20 @@ void PasswordReuseDetector::UseNonGaiaEnterprisePasswordHash( ...@@ -228,6 +227,20 @@ void PasswordReuseDetector::UseNonGaiaEnterprisePasswordHash(
enterprise_password_hash_data_list_ = std::move(password_hash_data_list); enterprise_password_hash_data_list_ = std::move(password_hash_data_list);
} }
void PasswordReuseDetector::UseEnterprisePasswordURLs(
base::Optional<std::vector<GURL>> enterprise_login_urls,
base::Optional<GURL> enterprise_change_password_url) {
enterprise_password_urls_ = std::move(enterprise_login_urls);
if (!enterprise_change_password_url.has_value() ||
!enterprise_change_password_url->is_valid()) {
return;
}
if (!enterprise_password_urls_)
enterprise_password_urls_ = base::make_optional<std::vector<GURL>>();
enterprise_password_urls_->push_back(enterprise_change_password_url.value());
}
void PasswordReuseDetector::ClearGaiaPasswordHash(const std::string& username) { void PasswordReuseDetector::ClearGaiaPasswordHash(const std::string& username) {
if (!gaia_password_hash_data_list_) if (!gaia_password_hash_data_list_)
return; return;
......
...@@ -65,14 +65,18 @@ class PasswordReuseDetector : public PasswordStoreConsumer { ...@@ -65,14 +65,18 @@ class PasswordReuseDetector : public PasswordStoreConsumer {
void UseNonGaiaEnterprisePasswordHash( void UseNonGaiaEnterprisePasswordHash(
base::Optional<std::vector<PasswordHashData>> password_hash_data_list); base::Optional<std::vector<PasswordHashData>> password_hash_data_list);
// Stores enterprise login URLs and change password URL.
// These URLs should be skipped in enterprise password reuse checking.
void UseEnterprisePasswordURLs(
base::Optional<std::vector<GURL>> enterprise_login_urls,
base::Optional<GURL> enterprise_change_password_url);
void ClearGaiaPasswordHash(const std::string& username); void ClearGaiaPasswordHash(const std::string& username);
void ClearAllGaiaPasswordHash(); void ClearAllGaiaPasswordHash();
void ClearAllEnterprisePasswordHash(); void ClearAllEnterprisePasswordHash();
void SetPrefs(PrefService* prefs) { prefs_ = prefs; }
private: private:
using passwords_iterator = std::map<base::string16, using passwords_iterator = std::map<base::string16,
std::set<std::string>, std::set<std::string>,
...@@ -127,7 +131,7 @@ class PasswordReuseDetector : public PasswordStoreConsumer { ...@@ -127,7 +131,7 @@ class PasswordReuseDetector : public PasswordStoreConsumer {
base::Optional<std::vector<PasswordHashData>> base::Optional<std::vector<PasswordHashData>>
enterprise_password_hash_data_list_; enterprise_password_hash_data_list_;
PrefService* prefs_; base::Optional<std::vector<GURL>> enterprise_password_urls_;
DISALLOW_COPY_AND_ASSIGN(PasswordReuseDetector); DISALLOW_COPY_AND_ASSIGN(PasswordReuseDetector);
}; };
......
...@@ -14,10 +14,6 @@ ...@@ -14,10 +14,6 @@
#include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/hash_password_manager.h" #include "components/password_manager/core/browser/hash_password_manager.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/safe_browsing/features.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -104,15 +100,13 @@ std::vector<PasswordHashData> PrepareEnterprisePasswordData( ...@@ -104,15 +100,13 @@ std::vector<PasswordHashData> PrepareEnterprisePasswordData(
return result; return result;
} }
void ConfigureEnterprisePasswordProtection(TestingPrefServiceSimple* prefs) { void ConfigureEnterprisePasswordProtection(
prefs->registry()->RegisterStringPref( PasswordReuseDetector* reuse_detector) {
prefs::kPasswordProtectionChangePasswordURL, ""); base::Optional<std::vector<GURL>> login_urls =
prefs->registry()->RegisterListPref(prefs::kPasswordProtectionLoginURLs); base::make_optional<std::vector<GURL>>();
prefs->SetString(prefs::kPasswordProtectionChangePasswordURL, login_urls->push_back(GURL("https://login.example.com"));
"https://changepassword.example.com/"); reuse_detector->UseEnterprisePasswordURLs(
base::ListValue login_urls; login_urls, GURL("https://changepassword.example.com/"));
login_urls.AppendString("https://login.example.com");
prefs->Set(prefs::kPasswordProtectionLoginURLs, login_urls);
} }
TEST(PasswordReuseDetectorTest, TypingPasswordOnDifferentSite) { TEST(PasswordReuseDetectorTest, TypingPasswordOnDifferentSite) {
...@@ -296,14 +290,8 @@ TEST(PasswordReuseDetectorTest, GaiaPasswordReuseFound) { ...@@ -296,14 +290,8 @@ TEST(PasswordReuseDetectorTest, GaiaPasswordReuseFound) {
} }
TEST(PasswordReuseDetectorTest, EnterprisePasswordNoReuse) { TEST(PasswordReuseDetectorTest, EnterprisePasswordNoReuse) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
safe_browsing::kEnterprisePasswordProtectionV1);
TestingPrefServiceSimple prefs;
ConfigureEnterprisePasswordProtection(&prefs);
PasswordReuseDetector reuse_detector; PasswordReuseDetector reuse_detector;
reuse_detector.SetPrefs(&prefs); ConfigureEnterprisePasswordProtection(&reuse_detector);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords())); reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer; MockPasswordReuseDetectorConsumer mockConsumer;
...@@ -330,14 +318,8 @@ TEST(PasswordReuseDetectorTest, EnterprisePasswordNoReuse) { ...@@ -330,14 +318,8 @@ TEST(PasswordReuseDetectorTest, EnterprisePasswordNoReuse) {
} }
TEST(PasswordReuseDetectorTest, EnterprisePasswordReuseFound) { TEST(PasswordReuseDetectorTest, EnterprisePasswordReuseFound) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
safe_browsing::kEnterprisePasswordProtectionV1);
TestingPrefServiceSimple prefs;
ConfigureEnterprisePasswordProtection(&prefs);
PasswordReuseDetector reuse_detector; PasswordReuseDetector reuse_detector;
reuse_detector.SetPrefs(&prefs); ConfigureEnterprisePasswordProtection(&reuse_detector);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords())); reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer; MockPasswordReuseDetectorConsumer mockConsumer;
...@@ -406,17 +388,11 @@ TEST(PasswordReuseDetectorTest, MatchSavedPasswordButNotGaiaPassword) { ...@@ -406,17 +388,11 @@ TEST(PasswordReuseDetectorTest, MatchSavedPasswordButNotGaiaPassword) {
} }
TEST(PasswordReuseDetectorTest, MatchEnterpriseAndMultipleSavedPasswords) { TEST(PasswordReuseDetectorTest, MatchEnterpriseAndMultipleSavedPasswords) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
safe_browsing::kEnterprisePasswordProtectionV1);
TestingPrefServiceSimple prefs;
ConfigureEnterprisePasswordProtection(&prefs);
const std::vector<std::pair<std::string, std::string>> domain_passwords = { const std::vector<std::pair<std::string, std::string>> domain_passwords = {
{"https://a.com", "34567890"}, {"https://b.com", "01234567890"}, {"https://a.com", "34567890"}, {"https://b.com", "01234567890"},
}; };
PasswordReuseDetector reuse_detector; PasswordReuseDetector reuse_detector;
reuse_detector.SetPrefs(&prefs); ConfigureEnterprisePasswordProtection(&reuse_detector);
reuse_detector.OnGetPasswordStoreResults(GetForms(domain_passwords)); reuse_detector.OnGetPasswordStoreResults(GetForms(domain_passwords));
std::string enterprise_password = "1234567890"; std::string enterprise_password = "1234567890";
...@@ -449,14 +425,8 @@ TEST(PasswordReuseDetectorTest, MatchEnterpriseAndMultipleSavedPasswords) { ...@@ -449,14 +425,8 @@ TEST(PasswordReuseDetectorTest, MatchEnterpriseAndMultipleSavedPasswords) {
} }
TEST(PasswordReuseDetectorTest, MatchSavedPasswordButNotEnterprisePassword) { TEST(PasswordReuseDetectorTest, MatchSavedPasswordButNotEnterprisePassword) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
safe_browsing::kEnterprisePasswordProtectionV1);
TestingPrefServiceSimple prefs;
ConfigureEnterprisePasswordProtection(&prefs);
PasswordReuseDetector reuse_detector; PasswordReuseDetector reuse_detector;
reuse_detector.SetPrefs(&prefs); ConfigureEnterprisePasswordProtection(&reuse_detector);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords())); reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer; MockPasswordReuseDetectorConsumer mockConsumer;
...@@ -472,17 +442,11 @@ TEST(PasswordReuseDetectorTest, MatchSavedPasswordButNotEnterprisePassword) { ...@@ -472,17 +442,11 @@ TEST(PasswordReuseDetectorTest, MatchSavedPasswordButNotEnterprisePassword) {
} }
TEST(PasswordReuseDetectorTest, MatchGaiaEnterpriseAndSavedPassword) { TEST(PasswordReuseDetectorTest, MatchGaiaEnterpriseAndSavedPassword) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
safe_browsing::kEnterprisePasswordProtectionV1);
TestingPrefServiceSimple prefs;
ConfigureEnterprisePasswordProtection(&prefs);
const std::vector<std::pair<std::string, std::string>> domain_passwords = { const std::vector<std::pair<std::string, std::string>> domain_passwords = {
{"https://a.com", "34567890"}, {"https://b.com", "01234567890"}, {"https://a.com", "34567890"}, {"https://b.com", "01234567890"},
}; };
PasswordReuseDetector reuse_detector; PasswordReuseDetector reuse_detector;
reuse_detector.SetPrefs(&prefs); ConfigureEnterprisePasswordProtection(&reuse_detector);
reuse_detector.OnGetPasswordStoreResults(GetForms(domain_passwords)); reuse_detector.OnGetPasswordStoreResults(GetForms(domain_passwords));
std::string gaia_password = "123456789"; std::string gaia_password = "123456789";
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
#include "components/password_manager/core/browser/password_store_signin_notifier.h" #include "components/password_manager/core/browser/password_store_signin_notifier.h"
#include "components/safe_browsing/common/safe_browsing_prefs.h"
#endif #endif
using autofill::PasswordForm; using autofill::PasswordForm;
...@@ -366,6 +367,7 @@ void PasswordStore::PrepareSyncPasswordHashData( ...@@ -366,6 +367,7 @@ void PasswordStore::PrepareSyncPasswordHashData(
// the migration. // the migration.
hash_password_manager_.MaybeMigrateExistingSyncPasswordHash(sync_username); hash_password_manager_.MaybeMigrateExistingSyncPasswordHash(sync_username);
SchedulePasswordHashUpdate(/*should_log_metrics=*/true); SchedulePasswordHashUpdate(/*should_log_metrics=*/true);
ScheduleEnterprisePasswordURLUpdate();
} }
void PasswordStore::SaveGaiaPasswordHash( void PasswordStore::SaveGaiaPasswordHash(
...@@ -433,6 +435,18 @@ void PasswordStore::SchedulePasswordHashUpdate(bool should_log_metrics) { ...@@ -433,6 +435,18 @@ void PasswordStore::SchedulePasswordHashUpdate(bool should_log_metrics) {
should_log_metrics)); should_log_metrics));
} }
void PasswordStore::ScheduleEnterprisePasswordURLUpdate() {
std::vector<GURL> enterprise_login_urls;
safe_browsing::GetPasswordProtectionLoginURLsPref(*prefs_,
&enterprise_login_urls);
GURL enterprise_change_password_url =
safe_browsing::GetPasswordProtectionChangePasswordURLPref(*prefs_);
ScheduleTask(base::BindRepeating(&PasswordStore::SaveEnterprisePasswordURLs,
this, base::Passed(&enterprise_login_urls),
enterprise_change_password_url));
}
#endif #endif
PasswordStore::~PasswordStore() { PasswordStore::~PasswordStore() {
...@@ -454,7 +468,6 @@ void PasswordStore::InitOnBackgroundSequence( ...@@ -454,7 +468,6 @@ void PasswordStore::InitOnBackgroundSequence(
// TODO(crbug.com/706392): Fix password reuse detection for Android. // TODO(crbug.com/706392): Fix password reuse detection for Android.
#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
reuse_detector_ = new PasswordReuseDetector; reuse_detector_ = new PasswordReuseDetector;
reuse_detector_->SetPrefs(prefs_);
GetAutofillableLoginsImpl( GetAutofillableLoginsImpl(
std::make_unique<GetLoginsRequest>(reuse_detector_)); std::make_unique<GetLoginsRequest>(reuse_detector_));
#endif #endif
...@@ -554,6 +567,15 @@ void PasswordStore::SaveProtectedPasswordHashImpl( ...@@ -554,6 +567,15 @@ void PasswordStore::SaveProtectedPasswordHashImpl(
std::move(enterprise_password_hash_list)); std::move(enterprise_password_hash_list));
} }
void PasswordStore::SaveEnterprisePasswordURLs(
const std::vector<GURL>& enterprise_login_urls,
const GURL& enterprise_change_password_url) {
if (!reuse_detector_)
return;
reuse_detector_->UseEnterprisePasswordURLs(std::move(enterprise_login_urls),
enterprise_change_password_url);
}
void PasswordStore::ClearProtectedPasswordHashImpl() { void PasswordStore::ClearProtectedPasswordHashImpl() {
// TODO(crbug.com/844134): Find a way to clear corresponding Gaia password // TODO(crbug.com/844134): Find a way to clear corresponding Gaia password
// hash when user logs out individual Gaia account in content area. // hash when user logs out individual Gaia account in content area.
......
...@@ -293,9 +293,13 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -293,9 +293,13 @@ class PasswordStore : protected PasswordStoreSync,
void SetPasswordStoreSigninNotifier( void SetPasswordStoreSigninNotifier(
std::unique_ptr<PasswordStoreSigninNotifier> notifier); std::unique_ptr<PasswordStoreSigninNotifier> notifier);
// Schedule the update of password hashes used by reuse detector. // Schedules the update of password hashes used by reuse detector.
void SchedulePasswordHashUpdate(bool should_log_metrics); void SchedulePasswordHashUpdate(bool should_log_metrics);
// Schedules the update of enterprise login and change password URLs.
// These URLs are used in enterprise password reuse detection.
void ScheduleEnterprisePasswordURLUpdate();
#endif #endif
protected: protected:
...@@ -483,6 +487,12 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -483,6 +487,12 @@ class PasswordStore : protected PasswordStoreSync,
PasswordHashDataList protected_password_data_list, PasswordHashDataList protected_password_data_list,
bool should_log_metrics); bool should_log_metrics);
// Propagates enterprise login urls and change password url to
// |reuse_detector_|.
void SaveEnterprisePasswordURLs(
const std::vector<GURL>& enterprise_login_urls,
const GURL& enterprise_change_password_url);
// Synchronous implementation of ClearProtectedPasswordHash(). // Synchronous implementation of ClearProtectedPasswordHash().
void ClearProtectedPasswordHashImpl(); void ClearProtectedPasswordHashImpl();
#endif #endif
......
...@@ -483,12 +483,15 @@ bool MatchesPasswordProtectionLoginURL(const GURL& url, ...@@ -483,12 +483,15 @@ bool MatchesPasswordProtectionLoginURL(const GURL& url,
std::vector<GURL> login_urls; std::vector<GURL> login_urls;
GetPasswordProtectionLoginURLsPref(prefs, &login_urls); GetPasswordProtectionLoginURLsPref(prefs, &login_urls);
if (login_urls.empty()) return MatchesURLList(url, login_urls);
return false; }
GURL simple_url = GetSimplifiedURL(url); bool MatchesURLList(const GURL& target_url, const std::vector<GURL> url_list) {
for (const GURL& login_url : login_urls) { if (url_list.empty() || !target_url.is_valid())
if (GetSimplifiedURL(login_url) == simple_url) { return false;
GURL simple_target_url = GetSimplifiedURL(target_url);
for (const GURL& url : url_list) {
if (GetSimplifiedURL(url) == simple_target_url) {
return true; return true;
} }
} }
......
...@@ -247,6 +247,9 @@ GURL GetPasswordProtectionChangePasswordURLPref(const PrefService& prefs); ...@@ -247,6 +247,9 @@ GURL GetPasswordProtectionChangePasswordURLPref(const PrefService& prefs);
bool MatchesPasswordProtectionChangePasswordURL(const GURL& url, bool MatchesPasswordProtectionChangePasswordURL(const GURL& url,
const PrefService& prefs); const PrefService& prefs);
// Helper function to match a |target_url| against |url_list|.
bool MatchesURLList(const GURL& target_url, const std::vector<GURL> url_list);
} // namespace safe_browsing } // namespace safe_browsing
#endif // COMPONENTS_SAFE_BROWSING_COMMON_SAFE_BROWSING_PREFS_H_ #endif // COMPONENTS_SAFE_BROWSING_COMMON_SAFE_BROWSING_PREFS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment