123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp
- index d22c29618897..08198d740a48 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp
- @@ -9,14 +9,6 @@
-
- namespace zxcvbn {
-
- -const Feedback DEFAULT_FEEDBACK = {
- - "",
- - {
- - "Use a few words, avoid common phrases",
- - "No need for symbols, digits, or uppercase letters",
- - },
- -};
- -
- static
- optional::optional<Feedback> get_match_feedback(const Match & match, bool is_sole_match);
-
- @@ -26,7 +18,15 @@ Feedback get_dictionary_match_feedback(const Match & match, bool is_sole_match);
- Feedback get_feedback(score_t score,
- const std::vector<Match> & sequence) {
- // starting feedback
- - if (!sequence.size()) return DEFAULT_FEEDBACK;
- + if (!sequence.size()) {
- + return {
- + "",
- + {
- + "Use a few words, avoid common phrases",
- + "No need for symbols, digits, or uppercase letters",
- + },
- + };
- + }
-
- // no feedback if score is good or great.
- if (score > 2) return {"", {}};
- @@ -151,12 +151,11 @@ Feedback get_dictionary_match_feedback(const Match & match_, bool is_sole_match)
-
- std::vector<std::string> suggestions;
- auto & word = match_.token;
- - if (std::regex_search(word, START_UPPER)) {
- + if (std::regex_search(word, START_UPPER())) {
- suggestions.push_back("Capitalization doesn't help very much");
- - }
- - else if (std::regex_search(word, ALL_UPPER) and
- - // XXX: UTF-8
- - util::ascii_lower(word) == word) {
- + } else if (std::regex_search(word, ALL_UPPER()) and
- + // XXX: UTF-8
- + util::ascii_lower(word) == word) {
- suggestions.push_back("All-uppercase is almost as easy to guess as all-lowercase");
- }
-
- @@ -171,4 +170,3 @@ Feedback get_dictionary_match_feedback(const Match & match_, bool is_sole_match)
- }
-
- }
- -
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp
- index c14e02618ec2..6d43cd2dc20b 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp
- @@ -19,28 +19,41 @@
- #include <utility>
- #include <unordered_set>
-
- +#include "base/no_destructor.h"
- +
- namespace zxcvbn {
-
- // TODO: make this a constexpr
- -extern const std::vector<std::pair<std::string, std::vector<std::string>>> L33T_TABLE = {
- - {"a", {"4", "@"}},
- - {"b", {"8"}},
- - {"c", {"(", "{", "[", "<"}},
- - {"e", {"3"}},
- - {"g", {"6", "9"}},
- - {"i", {"1", "!", "|"}},
- - {"l", {"1", "|", "7"}},
- - {"o", {"0"}},
- - {"s", {"$", "5"}},
- - {"t", {"+", "7"}},
- - {"x", {"%"}},
- - {"z", {"2"}},
- -};
- +const std::vector<std::pair<std::string, std::vector<std::string>>>&
- +L33T_TABLE() {
- + static base::NoDestructor<
- + std::vector<std::pair<std::string, std::vector<std::string>>>>
- + leet_table({
- + {"a", {"4", "@"}},
- + {"b", {"8"}},
- + {"c", {"(", "{", "[", "<"}},
- + {"e", {"3"}},
- + {"g", {"6", "9"}},
- + {"i", {"1", "!", "|"}},
- + {"l", {"1", "|", "7"}},
- + {"o", {"0"}},
- + {"s", {"$", "5"}},
- + {"t", {"+", "7"}},
- + {"x", {"%"}},
- + {"z", {"2"}},
- + });
- +
- + return *leet_table;
- +}
-
- // TODO: make this constexpr
- -extern const std::vector<std::pair<RegexTag, std::regex>> REGEXEN = {
- - {RegexTag::RECENT_YEAR, std::regex(R"(19\d\d|200\d|201\d)")},
- -};
- +const std::vector<std::pair<RegexTag, std::regex>>& REGEXEN() {
- + static base::NoDestructor<std::vector<std::pair<RegexTag, std::regex>>>
- + regexen({
- + {RegexTag::RECENT_YEAR, std::regex(R"(19\d\d|200\d|201\d)")},
- + });
- + return *regexen;
- +}
-
- const auto DATE_MAX_YEAR = 2050;
- const auto DATE_MIN_YEAR = 1000;
- @@ -115,19 +128,18 @@ std::vector<Match> omnimatch(const std::string & password,
- std::cref(ranked_dict)));
-
- std::vector<Match> matches;
- - std::function<std::vector<Match>(const std::string &)> matchers[] = {
- - std::bind(dictionary_match, std::placeholders::_1,
- - std::cref(ranked_dictionaries)),
- - std::bind(reverse_dictionary_match, std::placeholders::_1,
- - std::cref(ranked_dictionaries)),
- - std::bind(l33t_match, std::placeholders::_1,
- - std::cref(ranked_dictionaries), std::cref(L33T_TABLE)),
- - std::bind(spatial_match, std::placeholders::_1,
- - std::cref(graphs())),
- - repeat_match,
- - sequence_match,
- - std::bind(regex_match, std::placeholders::_1, std::cref(REGEXEN)),
- - date_match,
- + std::function<std::vector<Match>(const std::string&)> matchers[] = {
- + std::bind(dictionary_match, std::placeholders::_1,
- + std::cref(ranked_dictionaries)),
- + std::bind(reverse_dictionary_match, std::placeholders::_1,
- + std::cref(ranked_dictionaries)),
- + std::bind(l33t_match, std::placeholders::_1,
- + std::cref(ranked_dictionaries), std::cref(L33T_TABLE())),
- + std::bind(spatial_match, std::placeholders::_1, std::cref(graphs())),
- + repeat_match,
- + sequence_match,
- + std::bind(regex_match, std::placeholders::_1, std::cref(REGEXEN())),
- + date_match,
- };
- for (const auto & matcher : matchers) {
- auto ret = matcher(password);
- @@ -344,12 +356,13 @@ std::vector<Match> spatial_match(const std::string & password,
- return matches;
- }
-
- -const auto SHIFTED_RX = std::regex("[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?]");
- -
- static
- std::vector<Match> spatial_match_helper(const std::string & password,
- const Graph & graph,
- GraphTag graph_tag) {
- + const auto SHIFTED_RX =
- + std::regex("[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?]");
- +
- std::vector<Match> matches;
- if (!password.length()) return matches;
- idx_t idx = 0;
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp
- index 7ded5d89573f..ba73b909157c 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp
- @@ -10,8 +10,8 @@
-
- namespace zxcvbn {
-
- -extern const std::vector<std::pair<std::string, std::vector<std::string>>> L33T_TABLE;
- -extern const std::vector<std::pair<RegexTag, std::regex>> REGEXEN;
- +const std::vector<std::pair<std::string, std::vector<std::string>>>& L33T_TABLE();
- +const std::vector<std::pair<RegexTag, std::regex>>& REGEXEN();
-
- std::vector<Match> dictionary_match(const std::string & password,
- const RankedDicts & ranked_dictionaries);
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching_js_bindings.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching_js_bindings.cpp
- index 1dfcb53bc42d..1664a27b277c 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching_js_bindings.cpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching_js_bindings.cpp
- @@ -66,7 +66,7 @@ emscripten::val _dictionary_match(const std::wstring & wpassword,
- std::vector<std::pair<std::string, std::vector<std::string>>> _store;
- auto & ret2 = [&] () -> const std::vector<std::pair<std::string, std::vector<std::string>>> & {
- if (l33t_table.isUndefined()) {
- - return zxcvbn::L33T_TABLE;
- + return zxcvbn::L33T_TABLE();
- }
- else {
- auto ret = val_converter<std::unordered_map<std::string, std::vector<std::string>>>::from(l33t_table);
- @@ -198,7 +198,7 @@ emscripten::val repeat_match(const std::wstring & wpassword) {
-
- static
- emscripten::val regex_match(const std::wstring & wpassword) {
- - return to_val(zxcvbn::regex_match(to_utf8(wpassword), zxcvbn::REGEXEN));
- + return to_val(zxcvbn::regex_match(to_utf8(wpassword), zxcvbn::REGEXEN()));
- }
-
- static
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp
- index 96c4c76d1e65..fe2a2ec8cb8b 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp
- @@ -9,6 +9,8 @@
-
- #include <cmath>
-
- +#include "base/no_destructor.h"
- +
- namespace std {
-
- template<class T, class U>
- @@ -27,6 +29,26 @@ const auto MIN_GUESSES_BEFORE_GROWING_SEQUENCE = static_cast<guesses_t>(10000);
- const auto MIN_SUBMATCH_GUESSES_SINGLE_CHAR = static_cast<guesses_t>(10);
- const auto MIN_SUBMATCH_GUESSES_MULTI_CHAR = static_cast<guesses_t>(50);
-
- +const std::regex& START_UPPER() {
- + static base::NoDestructor<std::regex> start_upper(R"(^[A-Z][^A-Z]+$)");
- + return *start_upper;
- +}
- +
- +const std::regex& END_UPPER() {
- + static base::NoDestructor<std::regex> end_upper(R"(^[^A-Z]+[A-Z]$)");
- + return *end_upper;
- +}
- +
- +const std::regex& ALL_UPPER() {
- + static base::NoDestructor<std::regex> all_upper(R"(^[^a-z]+$)");
- + return *all_upper;
- +}
- +
- +const std::regex& ALL_LOWER() {
- + static base::NoDestructor<std::regex> all_lower(R"(^[^A-Z]+$)");
- + return *all_lower;
- +}
- +
- template<class Tret, class Tin>
- Tret factorial(Tin n) {
- // unoptimized, called only on small n
- @@ -441,11 +463,12 @@ guesses_t dictionary_guesses(const Match & match) {
-
- guesses_t uppercase_variations(const Match & match) {
- auto & word = match.token;
- - if (std::regex_match(word, ALL_LOWER) || !word.size()) return 1;
- + if (std::regex_match(word, ALL_LOWER()) || !word.size())
- + return 1;
- // a capitalized word is the most common capitalization scheme,
- // so it only doubles the search space (uncapitalized + capitalized).
- // allcaps and end-capitalized are common enough too, underestimate as 2x factor to be safe.
- - for (const auto & regex : {START_UPPER, END_UPPER, ALL_UPPER}) {
- + for (const auto& regex : {START_UPPER(), END_UPPER(), ALL_UPPER()}) {
- if (std::regex_match(word, regex)) return 2;
- }
- // otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp
- index ec9fd22d8e18..1038ee34587c 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp
- @@ -11,10 +11,10 @@
-
- namespace zxcvbn {
-
- -const auto START_UPPER = std::regex(R"(^[A-Z][^A-Z]+$)");
- -const auto END_UPPER = std::regex(R"(^[^A-Z]+[A-Z]$)");
- -const auto ALL_UPPER = std::regex(R"(^[^a-z]+$)");
- -const auto ALL_LOWER = std::regex(R"(^[^A-Z]+$)");
- +const std::regex& START_UPPER();
- +const std::regex& END_UPPER();
- +const std::regex& ALL_UPPER();
- +const std::regex& ALL_LOWER();
-
- const guesses_t MIN_YEAR_SPACE = 20;
- const auto REFERENCE_YEAR = 2016;
- diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
- index 084d3cc0cd7c..107bce0af064 100644
- --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
- +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
- @@ -8,6 +8,8 @@
-
- #include <cassert>
-
- +#include "base/no_destructor.h"
- +
- namespace zxcvbn {
-
- namespace util {
- @@ -32,7 +34,10 @@ std::string reverse_string(const std::string & in) {
- return conv.to_bytes(ret);
- }
-
- -const std::codecvt_utf8<char32_t> char32_conv;
- +const std::codecvt_utf8<char32_t>& char32_conv() {
- + static base::NoDestructor<std::codecvt_utf8<char32_t>> char32_conv;
- + return *char32_conv;
- +}
-
- bool utf8_valid(std::string::const_iterator start,
- std::string::const_iterator end) {
- @@ -46,8 +51,8 @@ bool utf8_valid(std::string::const_iterator start,
- char32_t new_char;
- char32_t *to_next;
-
- - auto res = char32_conv.in(st, from, from_end, from_next,
- - &new_char, &new_char + 1, to_next);
- + auto res = char32_conv().in(st, from, from_end, from_next, &new_char,
- + &new_char + 1, to_next);
- if (!((res == std::codecvt_utf8<char32_t>::result::partial &&
- from_next != from_end) ||
- (res == std::codecvt_utf8<char32_t>::result::ok &&
- @@ -67,7 +72,7 @@ template<class It>
- It _utf8_iter(It start, It end) {
- assert(start != end);
- std::mbstate_t st;
- - auto amt = char32_conv.length(st, &*start, &*end, 1);
- + auto amt = char32_conv().length(st, &*start, &*end, 1);
- return start + amt;
- }
-
- @@ -110,8 +115,8 @@ std::pair<char32_t, It> _utf8_decode(It it, It end) {
- const char *from = &*it;
- const char *from_end = &*end;
- const char *from_next;
- - auto res = char32_conv.in(st, from, from_end, from_next,
- - &new_char, &new_char + 1, to_next);
- + auto res = char32_conv().in(st, from, from_end, from_next, &new_char,
- + &new_char + 1, to_next);
- assert((res == std::codecvt_utf8<char32_t>::result::partial &&
- from_next != from_end) ||
- (res == std::codecvt_utf8<char32_t>::result::ok &&
|