Commit 085e76f6 authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[Passwords] Parse zxcvbn dicts in background

This change updates the zxcvbn data component and library to support
parsing the data dictionaries on the background thread.

Fixed: 1112461
Change-Id: I1b553bf448c1baf9b0a1359a853fc5360716e52a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2332609Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797629}
parent 45df86d3
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/strings/string_split.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/util/ranges/algorithm.h" #include "base/util/ranges/algorithm.h"
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
#include "components/update_client/update_client_errors.h" #include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h" #include "components/update_client/utils.h"
#include "third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp" #include "third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp"
#include "third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists_common.hpp"
namespace component_updater { namespace component_updater {
...@@ -69,33 +71,27 @@ constexpr std::array<TagAndFileName, 6> kTagAndFileNamePairs = {{ ...@@ -69,33 +71,27 @@ constexpr std::array<TagAndFileName, 6> kTagAndFileNamePairs = {{
ZxcvbnDataComponentInstallerPolicy::kUsTvAndFilmTxtFileName}, ZxcvbnDataComponentInstallerPolicy::kUsTvAndFilmTxtFileName},
}}; }};
using DictionaryMap = base::flat_map<zxcvbn::DictionaryTag, std::string>; using RankedDictionaries =
DictionaryMap ReadDictionaries(const base::FilePath& install_dir) { std::unordered_map<zxcvbn::DictionaryTag, zxcvbn::RankedDict>;
DictionaryMap result; RankedDictionaries ParseRankedDictionaries(const base::FilePath& install_dir) {
result.reserve(kTagAndFileNamePairs.size()); RankedDictionaries result;
for (const auto& pair : kTagAndFileNamePairs) { for (const auto& pair : kTagAndFileNamePairs) {
base::FilePath dictionary_path = install_dir.Append(pair.file_name); base::FilePath dictionary_path = install_dir.Append(pair.file_name);
DVLOG(1) << "Reading Dictionary from file: " << dictionary_path; DVLOG(1) << "Reading Dictionary from file: " << dictionary_path;
std::string dictionary; std::string dictionary;
if (base::ReadFileToString(dictionary_path, &dictionary)) if (base::ReadFileToString(dictionary_path, &dictionary)) {
result.try_emplace(result.end(), pair.tag, std::move(dictionary)); result.emplace(pair.tag, zxcvbn::build_ranked_dict(base::SplitStringPiece(
else dictionary, "\r\n", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY)));
} else {
VLOG(1) << "Failed reading from " << dictionary_path; VLOG(1) << "Failed reading from " << dictionary_path;
}
} }
return result; return result;
} }
void ParseDictionaries(const DictionaryMap& dictionaries) {
for (const auto& pair : dictionaries) {
if (!zxcvbn::ParseRankedDictionary(pair.first, pair.second)) {
VLOG(1) << "Failed to parse dictionary for tag "
<< static_cast<int>(pair.first) << ". Contents: " << pair.second;
}
}
}
// The SHA256 of the SubjectPublicKeyInfo used to sign the extension. // The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
// The extension id is: ojhpjlocmbogdgmfpkhlaaeamibhnphh // The extension id is: ojhpjlocmbogdgmfpkhlaaeamibhnphh
constexpr std::array<uint8_t, 32> kZxcvbnDataPublicKeySha256 = { constexpr std::array<uint8_t, 32> kZxcvbnDataPublicKeySha256 = {
...@@ -141,8 +137,8 @@ void ZxcvbnDataComponentInstallerPolicy::ComponentReady( ...@@ -141,8 +137,8 @@ void ZxcvbnDataComponentInstallerPolicy::ComponentReady(
base::ThreadPool::PostTaskAndReplyWithResult( base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&ReadDictionaries, install_dir), base::BindOnce(&ParseRankedDictionaries, install_dir),
base::BindOnce(&ParseDictionaries)); base::BindOnce(&zxcvbn::SetRankedDicts));
} }
base::FilePath ZxcvbnDataComponentInstallerPolicy::GetRelativeInstallDir() base::FilePath ZxcvbnDataComponentInstallerPolicy::GetRelativeInstallDir()
......
...@@ -17,8 +17,8 @@ namespace component_updater { ...@@ -17,8 +17,8 @@ namespace component_updater {
namespace { namespace {
using ::testing::ElementsAre;
using ::testing::Pair; using ::testing::Pair;
using ::testing::UnorderedElementsAre;
} // namespace } // namespace
...@@ -103,15 +103,15 @@ TEST_F(ZxcvbnDataComponentInstallerPolicyTest, ComponentReady) { ...@@ -103,15 +103,15 @@ TEST_F(ZxcvbnDataComponentInstallerPolicyTest, ComponentReady) {
base::WriteFile( base::WriteFile(
GetPath().Append( GetPath().Append(
ZxcvbnDataComponentInstallerPolicy::kEnglishWikipediaTxtFileName), ZxcvbnDataComponentInstallerPolicy::kEnglishWikipediaTxtFileName),
"english_wikipedia"); "english\nwikipedia");
base::WriteFile( base::WriteFile(
GetPath().Append( GetPath().Append(
ZxcvbnDataComponentInstallerPolicy::kFemaleNamesTxtFileName), ZxcvbnDataComponentInstallerPolicy::kFemaleNamesTxtFileName),
"female_names"); "female\nnames");
base::WriteFile( base::WriteFile(
GetPath().Append( GetPath().Append(
ZxcvbnDataComponentInstallerPolicy::kMaleNamesTxtFileName), ZxcvbnDataComponentInstallerPolicy::kMaleNamesTxtFileName),
"male_names"); "male\nnames");
base::WriteFile( base::WriteFile(
GetPath().Append( GetPath().Append(
ZxcvbnDataComponentInstallerPolicy::kPasswordsTxtFileName), ZxcvbnDataComponentInstallerPolicy::kPasswordsTxtFileName),
...@@ -122,26 +122,28 @@ TEST_F(ZxcvbnDataComponentInstallerPolicyTest, ComponentReady) { ...@@ -122,26 +122,28 @@ TEST_F(ZxcvbnDataComponentInstallerPolicyTest, ComponentReady) {
base::WriteFile( base::WriteFile(
GetPath().Append( GetPath().Append(
ZxcvbnDataComponentInstallerPolicy::kUsTvAndFilmTxtFileName), ZxcvbnDataComponentInstallerPolicy::kUsTvAndFilmTxtFileName),
"us_tv_and_film"); "us\ntv\nand\nfilm");
policy().ComponentReady(version(), GetPath(), nullptr); policy().ComponentReady(version(), GetPath(), nullptr);
task_env().RunUntilIdle(); task_env().RunUntilIdle();
zxcvbn::RankedDicts ranked_dicts = zxcvbn::default_ranked_dicts(); zxcvbn::RankedDicts ranked_dicts = zxcvbn::default_ranked_dicts();
EXPECT_THAT(zxcvbn::default_ranked_dicts(), EXPECT_THAT(
::testing::UnorderedElementsAre( zxcvbn::default_ranked_dicts(),
Pair(zxcvbn::DictionaryTag::ENGLISH_WIKIPEDIA, UnorderedElementsAre(
ElementsAre(Pair("english_wikipedia", 1))), Pair(zxcvbn::DictionaryTag::ENGLISH_WIKIPEDIA,
Pair(zxcvbn::DictionaryTag::FEMALE_NAMES, UnorderedElementsAre(Pair("english", 1), Pair("wikipedia", 2))),
ElementsAre(Pair("female_names", 1))), Pair(zxcvbn::DictionaryTag::FEMALE_NAMES,
Pair(zxcvbn::DictionaryTag::MALE_NAMES, UnorderedElementsAre(Pair("female", 1), Pair("names", 2))),
ElementsAre(Pair("male_names", 1))), Pair(zxcvbn::DictionaryTag::MALE_NAMES,
Pair(zxcvbn::DictionaryTag::PASSWORDS, UnorderedElementsAre(Pair("male", 1), Pair("names", 2))),
ElementsAre(Pair("passwords", 1))), Pair(zxcvbn::DictionaryTag::PASSWORDS,
Pair(zxcvbn::DictionaryTag::SURNAMES, UnorderedElementsAre(Pair("passwords", 1))),
ElementsAre(Pair("surnames", 1))), Pair(zxcvbn::DictionaryTag::SURNAMES,
Pair(zxcvbn::DictionaryTag::US_TV_AND_FILM, UnorderedElementsAre(Pair("surnames", 1))),
ElementsAre(Pair("us_tv_and_film", 1))))); Pair(zxcvbn::DictionaryTag::US_TV_AND_FILM,
UnorderedElementsAre(Pair("us", 1), Pair("tv", 2),
Pair("and", 3), Pair("film", 4)))));
} }
} // namespace component_updater } // namespace component_updater
#include <zxcvbn/frequency_lists.hpp> #include <zxcvbn/frequency_lists.hpp>
#include <unordered_map> #include <unordered_map>
#include <utility>
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/strings/string_split.h"
#include "base/strings/string_piece.h"
namespace zxcvbn { namespace zxcvbn {
...@@ -16,16 +15,10 @@ std::unordered_map<DictionaryTag, RankedDict>& ranked_dicts() { ...@@ -16,16 +15,10 @@ std::unordered_map<DictionaryTag, RankedDict>& ranked_dicts() {
return *ranked_dicts; return *ranked_dicts;
} }
} } // namespace
bool ParseRankedDictionary(DictionaryTag tag, base::StringPiece str) {
RankedDict& dict = ranked_dicts()[tag];
if (!dict.empty())
return false;
dict = build_ranked_dict(base::SplitStringPiece( void SetRankedDicts(std::unordered_map<DictionaryTag, RankedDict> dicts) {
str, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)); ranked_dicts() = std::move(dicts);
return true;
} }
RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts) { RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts) {
......
...@@ -38,7 +38,7 @@ namespace zxcvbn { ...@@ -38,7 +38,7 @@ namespace zxcvbn {
using RankedDicts = std::unordered_map<DictionaryTag, const RankedDict &>; using RankedDicts = std::unordered_map<DictionaryTag, const RankedDict &>;
bool ParseRankedDictionary(DictionaryTag tag, base::StringPiece str); void SetRankedDicts(std::unordered_map<DictionaryTag, RankedDict> dicts);
RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts); RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts);
RankedDicts default_ranked_dicts(); RankedDicts default_ranked_dicts();
......
diff --git a/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py b/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py diff --git a/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py b/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py
index d5504e073cb3..9be1391c5aa9 100755 index d5504e0..9be1391 100755
--- a/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py --- a/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py
+++ b/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py +++ b/third_party/zxcvbn-cpp/data-scripts/build_frequency_lists.py
@@ -122,8 +122,7 @@ def to_kv(lst, lst_name): @@ -122,8 +122,7 @@ def to_kv(lst, lst_name):
...@@ -37,20 +37,19 @@ index d5504e073cb3..9be1391c5aa9 100755 ...@@ -37,20 +37,19 @@ index d5504e073cb3..9be1391c5aa9 100755
output_fn = output_coffee output_fn = output_coffee
diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp
index 4e4b72756e34..17c73a67bd0a 100644 index 4e4b727..a7adbe9 100644
--- a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp
+++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.cpp
@@ -1,11 +1,33 @@ @@ -1,11 +1,26 @@
#include <zxcvbn/frequency_lists.hpp> #include <zxcvbn/frequency_lists.hpp>
-#include <zxcvbn/_frequency_lists.hpp> -#include <zxcvbn/_frequency_lists.hpp>
- -
#include <unordered_map> #include <unordered_map>
+#include <utility>
+#include "base/no_destructor.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_piece.h"
+ +
+#include "base/no_destructor.h"
namespace zxcvbn { namespace zxcvbn {
+namespace { +namespace {
...@@ -61,22 +60,16 @@ index 4e4b72756e34..17c73a67bd0a 100644 ...@@ -61,22 +60,16 @@ index 4e4b72756e34..17c73a67bd0a 100644
+ return *ranked_dicts; + return *ranked_dicts;
+} +}
+ +
+} +} // namespace
+
+bool ParseRankedDictionary(DictionaryTag tag, base::StringPiece str) {
+ RankedDict& dict = ranked_dicts()[tag];
+ if (!dict.empty())
+ return false;
+ +
+ dict = build_ranked_dict(base::SplitStringPiece( +void SetRankedDicts(std::unordered_map<DictionaryTag, RankedDict> dicts) {
+ str, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)); + ranked_dicts() = std::move(dicts);
+ return true;
+} +}
+ +
RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts) { RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts) {
RankedDicts build; RankedDicts build;
@@ -17,8 +39,7 @@ RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict @@ -17,8 +32,7 @@ RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict
} }
RankedDicts default_ranked_dicts() { RankedDicts default_ranked_dicts() {
...@@ -87,10 +80,10 @@ index 4e4b72756e34..17c73a67bd0a 100644 ...@@ -87,10 +80,10 @@ index 4e4b72756e34..17c73a67bd0a 100644
- -
} }
diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp
index c75ea30d5a91..191842fb530c 100644 index c75ea30..634ecb2 100644
--- a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp
+++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp
@@ -2,15 +2,24 @@ @@ -2,7 +2,6 @@
#define __ZXCVBN__FREQUENCY_LISTS_HPP #define __ZXCVBN__FREQUENCY_LISTS_HPP
#include <zxcvbn/frequency_lists_common.hpp> #include <zxcvbn/frequency_lists_common.hpp>
...@@ -98,10 +91,8 @@ index c75ea30d5a91..191842fb530c 100644 ...@@ -98,10 +91,8 @@ index c75ea30d5a91..191842fb530c 100644
#include <unordered_map> #include <unordered_map>
#include <cstdint> @@ -10,7 +9,15 @@
+#include "base/strings/string_piece.h"
+
namespace zxcvbn { namespace zxcvbn {
-using DictionaryTag = _frequency_lists::DictionaryTag; -using DictionaryTag = _frequency_lists::DictionaryTag;
...@@ -117,11 +108,11 @@ index c75ea30d5a91..191842fb530c 100644 ...@@ -117,11 +108,11 @@ index c75ea30d5a91..191842fb530c 100644
} }
@@ -29,6 +38,8 @@ namespace zxcvbn { @@ -29,6 +36,8 @@ namespace zxcvbn {
using RankedDicts = std::unordered_map<DictionaryTag, const RankedDict &>; using RankedDicts = std::unordered_map<DictionaryTag, const RankedDict &>;
+bool ParseRankedDictionary(DictionaryTag tag, base::StringPiece str); +void SetRankedDicts(std::unordered_map<DictionaryTag, RankedDict> dicts);
+ +
RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts); RankedDicts convert_to_ranked_dicts(std::unordered_map<DictionaryTag, RankedDict> & ranked_dicts);
RankedDicts default_ranked_dicts(); RankedDicts default_ranked_dicts();
......
...@@ -304,7 +304,7 @@ TEST(ZxcvbnTest, DictionaryMatching) { ...@@ -304,7 +304,7 @@ TEST(ZxcvbnTest, DictionaryMatching) {
{ {
// default dictionaries // default dictionaries
ParseRankedDictionary(DictionaryTag::US_TV_AND_FILM, "wow"); SetRankedDicts({{DictionaryTag::US_TV_AND_FILM, {{"wow", 1}}}});
std::vector<Match> matches = std::vector<Match> matches =
dictionary_match("wow", default_ranked_dicts()); dictionary_match("wow", default_ranked_dicts());
EXPECT_THAT(matches, ElementsAre(ExpectedDictionaryMatch{ EXPECT_THAT(matches, ElementsAre(ExpectedDictionaryMatch{
...@@ -319,7 +319,7 @@ TEST(ZxcvbnTest, DictionaryMatching) { ...@@ -319,7 +319,7 @@ TEST(ZxcvbnTest, DictionaryMatching) {
{ {
// matches with provided user input dictionary // matches with provided user input dictionary
ParseRankedDictionary(DictionaryTag::USER_INPUTS, "foo\nbar"); SetRankedDicts({{DictionaryTag::USER_INPUTS, {{"foo", 1}, {"bar", 2}}}});
std::vector<Match> matches = std::vector<Match> matches =
dictionary_match("foobar", default_ranked_dicts()); dictionary_match("foobar", default_ranked_dicts());
EXPECT_THAT(matches, ElementsAre( EXPECT_THAT(matches, ElementsAre(
...@@ -1004,7 +1004,8 @@ TEST(ZxcvbnTest, DateMatching) { ...@@ -1004,7 +1004,8 @@ TEST(ZxcvbnTest, DateMatching) {
TEST(ZxcvbnTest, Omnimatch) { TEST(ZxcvbnTest, Omnimatch) {
EXPECT_THAT(omnimatch(""), IsEmpty()); EXPECT_THAT(omnimatch(""), IsEmpty());
ParseRankedDictionary(DictionaryTag::ENGLISH_WIKIPEDIA, "rosebud\nmaelstrom"); SetRankedDicts(
{{DictionaryTag::ENGLISH_WIKIPEDIA, {{"rosebud", 1}, {"maelstrom", 2}}}});
std::string password = "r0sebudmaelstrom11/20/91aaaa"; std::string password = "r0sebudmaelstrom11/20/91aaaa";
std::vector<Match> matches = omnimatch(password); std::vector<Match> matches = omnimatch(password);
......
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