no_static_initializers.diff 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp
  2. index d22c29618897..08198d740a48 100644
  3. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp
  4. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/feedback.cpp
  5. @@ -9,14 +9,6 @@
  6. namespace zxcvbn {
  7. -const Feedback DEFAULT_FEEDBACK = {
  8. - "",
  9. - {
  10. - "Use a few words, avoid common phrases",
  11. - "No need for symbols, digits, or uppercase letters",
  12. - },
  13. -};
  14. -
  15. static
  16. optional::optional<Feedback> get_match_feedback(const Match & match, bool is_sole_match);
  17. @@ -26,7 +18,15 @@ Feedback get_dictionary_match_feedback(const Match & match, bool is_sole_match);
  18. Feedback get_feedback(score_t score,
  19. const std::vector<Match> & sequence) {
  20. // starting feedback
  21. - if (!sequence.size()) return DEFAULT_FEEDBACK;
  22. + if (!sequence.size()) {
  23. + return {
  24. + "",
  25. + {
  26. + "Use a few words, avoid common phrases",
  27. + "No need for symbols, digits, or uppercase letters",
  28. + },
  29. + };
  30. + }
  31. // no feedback if score is good or great.
  32. if (score > 2) return {"", {}};
  33. @@ -151,12 +151,11 @@ Feedback get_dictionary_match_feedback(const Match & match_, bool is_sole_match)
  34. std::vector<std::string> suggestions;
  35. auto & word = match_.token;
  36. - if (std::regex_search(word, START_UPPER)) {
  37. + if (std::regex_search(word, START_UPPER())) {
  38. suggestions.push_back("Capitalization doesn't help very much");
  39. - }
  40. - else if (std::regex_search(word, ALL_UPPER) and
  41. - // XXX: UTF-8
  42. - util::ascii_lower(word) == word) {
  43. + } else if (std::regex_search(word, ALL_UPPER()) and
  44. + // XXX: UTF-8
  45. + util::ascii_lower(word) == word) {
  46. suggestions.push_back("All-uppercase is almost as easy to guess as all-lowercase");
  47. }
  48. @@ -171,4 +170,3 @@ Feedback get_dictionary_match_feedback(const Match & match_, bool is_sole_match)
  49. }
  50. }
  51. -
  52. diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp
  53. index c14e02618ec2..6d43cd2dc20b 100644
  54. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp
  55. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp
  56. @@ -19,28 +19,41 @@
  57. #include <utility>
  58. #include <unordered_set>
  59. +#include "base/no_destructor.h"
  60. +
  61. namespace zxcvbn {
  62. // TODO: make this a constexpr
  63. -extern const std::vector<std::pair<std::string, std::vector<std::string>>> L33T_TABLE = {
  64. - {"a", {"4", "@"}},
  65. - {"b", {"8"}},
  66. - {"c", {"(", "{", "[", "<"}},
  67. - {"e", {"3"}},
  68. - {"g", {"6", "9"}},
  69. - {"i", {"1", "!", "|"}},
  70. - {"l", {"1", "|", "7"}},
  71. - {"o", {"0"}},
  72. - {"s", {"$", "5"}},
  73. - {"t", {"+", "7"}},
  74. - {"x", {"%"}},
  75. - {"z", {"2"}},
  76. -};
  77. +const std::vector<std::pair<std::string, std::vector<std::string>>>&
  78. +L33T_TABLE() {
  79. + static base::NoDestructor<
  80. + std::vector<std::pair<std::string, std::vector<std::string>>>>
  81. + leet_table({
  82. + {"a", {"4", "@"}},
  83. + {"b", {"8"}},
  84. + {"c", {"(", "{", "[", "<"}},
  85. + {"e", {"3"}},
  86. + {"g", {"6", "9"}},
  87. + {"i", {"1", "!", "|"}},
  88. + {"l", {"1", "|", "7"}},
  89. + {"o", {"0"}},
  90. + {"s", {"$", "5"}},
  91. + {"t", {"+", "7"}},
  92. + {"x", {"%"}},
  93. + {"z", {"2"}},
  94. + });
  95. +
  96. + return *leet_table;
  97. +}
  98. // TODO: make this constexpr
  99. -extern const std::vector<std::pair<RegexTag, std::regex>> REGEXEN = {
  100. - {RegexTag::RECENT_YEAR, std::regex(R"(19\d\d|200\d|201\d)")},
  101. -};
  102. +const std::vector<std::pair<RegexTag, std::regex>>& REGEXEN() {
  103. + static base::NoDestructor<std::vector<std::pair<RegexTag, std::regex>>>
  104. + regexen({
  105. + {RegexTag::RECENT_YEAR, std::regex(R"(19\d\d|200\d|201\d)")},
  106. + });
  107. + return *regexen;
  108. +}
  109. const auto DATE_MAX_YEAR = 2050;
  110. const auto DATE_MIN_YEAR = 1000;
  111. @@ -115,19 +128,18 @@ std::vector<Match> omnimatch(const std::string & password,
  112. std::cref(ranked_dict)));
  113. std::vector<Match> matches;
  114. - std::function<std::vector<Match>(const std::string &)> matchers[] = {
  115. - std::bind(dictionary_match, std::placeholders::_1,
  116. - std::cref(ranked_dictionaries)),
  117. - std::bind(reverse_dictionary_match, std::placeholders::_1,
  118. - std::cref(ranked_dictionaries)),
  119. - std::bind(l33t_match, std::placeholders::_1,
  120. - std::cref(ranked_dictionaries), std::cref(L33T_TABLE)),
  121. - std::bind(spatial_match, std::placeholders::_1,
  122. - std::cref(graphs())),
  123. - repeat_match,
  124. - sequence_match,
  125. - std::bind(regex_match, std::placeholders::_1, std::cref(REGEXEN)),
  126. - date_match,
  127. + std::function<std::vector<Match>(const std::string&)> matchers[] = {
  128. + std::bind(dictionary_match, std::placeholders::_1,
  129. + std::cref(ranked_dictionaries)),
  130. + std::bind(reverse_dictionary_match, std::placeholders::_1,
  131. + std::cref(ranked_dictionaries)),
  132. + std::bind(l33t_match, std::placeholders::_1,
  133. + std::cref(ranked_dictionaries), std::cref(L33T_TABLE())),
  134. + std::bind(spatial_match, std::placeholders::_1, std::cref(graphs())),
  135. + repeat_match,
  136. + sequence_match,
  137. + std::bind(regex_match, std::placeholders::_1, std::cref(REGEXEN())),
  138. + date_match,
  139. };
  140. for (const auto & matcher : matchers) {
  141. auto ret = matcher(password);
  142. @@ -344,12 +356,13 @@ std::vector<Match> spatial_match(const std::string & password,
  143. return matches;
  144. }
  145. -const auto SHIFTED_RX = std::regex("[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?]");
  146. -
  147. static
  148. std::vector<Match> spatial_match_helper(const std::string & password,
  149. const Graph & graph,
  150. GraphTag graph_tag) {
  151. + const auto SHIFTED_RX =
  152. + std::regex("[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?]");
  153. +
  154. std::vector<Match> matches;
  155. if (!password.length()) return matches;
  156. idx_t idx = 0;
  157. diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp
  158. index 7ded5d89573f..ba73b909157c 100644
  159. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp
  160. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.hpp
  161. @@ -10,8 +10,8 @@
  162. namespace zxcvbn {
  163. -extern const std::vector<std::pair<std::string, std::vector<std::string>>> L33T_TABLE;
  164. -extern const std::vector<std::pair<RegexTag, std::regex>> REGEXEN;
  165. +const std::vector<std::pair<std::string, std::vector<std::string>>>& L33T_TABLE();
  166. +const std::vector<std::pair<RegexTag, std::regex>>& REGEXEN();
  167. std::vector<Match> dictionary_match(const std::string & password,
  168. const RankedDicts & ranked_dictionaries);
  169. 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
  170. index 1dfcb53bc42d..1664a27b277c 100644
  171. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching_js_bindings.cpp
  172. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching_js_bindings.cpp
  173. @@ -66,7 +66,7 @@ emscripten::val _dictionary_match(const std::wstring & wpassword,
  174. std::vector<std::pair<std::string, std::vector<std::string>>> _store;
  175. auto & ret2 = [&] () -> const std::vector<std::pair<std::string, std::vector<std::string>>> & {
  176. if (l33t_table.isUndefined()) {
  177. - return zxcvbn::L33T_TABLE;
  178. + return zxcvbn::L33T_TABLE();
  179. }
  180. else {
  181. auto ret = val_converter<std::unordered_map<std::string, std::vector<std::string>>>::from(l33t_table);
  182. @@ -198,7 +198,7 @@ emscripten::val repeat_match(const std::wstring & wpassword) {
  183. static
  184. emscripten::val regex_match(const std::wstring & wpassword) {
  185. - return to_val(zxcvbn::regex_match(to_utf8(wpassword), zxcvbn::REGEXEN));
  186. + return to_val(zxcvbn::regex_match(to_utf8(wpassword), zxcvbn::REGEXEN()));
  187. }
  188. static
  189. diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp
  190. index 96c4c76d1e65..fe2a2ec8cb8b 100644
  191. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp
  192. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.cpp
  193. @@ -9,6 +9,8 @@
  194. #include <cmath>
  195. +#include "base/no_destructor.h"
  196. +
  197. namespace std {
  198. template<class T, class U>
  199. @@ -27,6 +29,26 @@ const auto MIN_GUESSES_BEFORE_GROWING_SEQUENCE = static_cast<guesses_t>(10000);
  200. const auto MIN_SUBMATCH_GUESSES_SINGLE_CHAR = static_cast<guesses_t>(10);
  201. const auto MIN_SUBMATCH_GUESSES_MULTI_CHAR = static_cast<guesses_t>(50);
  202. +const std::regex& START_UPPER() {
  203. + static base::NoDestructor<std::regex> start_upper(R"(^[A-Z][^A-Z]+$)");
  204. + return *start_upper;
  205. +}
  206. +
  207. +const std::regex& END_UPPER() {
  208. + static base::NoDestructor<std::regex> end_upper(R"(^[^A-Z]+[A-Z]$)");
  209. + return *end_upper;
  210. +}
  211. +
  212. +const std::regex& ALL_UPPER() {
  213. + static base::NoDestructor<std::regex> all_upper(R"(^[^a-z]+$)");
  214. + return *all_upper;
  215. +}
  216. +
  217. +const std::regex& ALL_LOWER() {
  218. + static base::NoDestructor<std::regex> all_lower(R"(^[^A-Z]+$)");
  219. + return *all_lower;
  220. +}
  221. +
  222. template<class Tret, class Tin>
  223. Tret factorial(Tin n) {
  224. // unoptimized, called only on small n
  225. @@ -441,11 +463,12 @@ guesses_t dictionary_guesses(const Match & match) {
  226. guesses_t uppercase_variations(const Match & match) {
  227. auto & word = match.token;
  228. - if (std::regex_match(word, ALL_LOWER) || !word.size()) return 1;
  229. + if (std::regex_match(word, ALL_LOWER()) || !word.size())
  230. + return 1;
  231. // a capitalized word is the most common capitalization scheme,
  232. // so it only doubles the search space (uncapitalized + capitalized).
  233. // allcaps and end-capitalized are common enough too, underestimate as 2x factor to be safe.
  234. - for (const auto & regex : {START_UPPER, END_UPPER, ALL_UPPER}) {
  235. + for (const auto& regex : {START_UPPER(), END_UPPER(), ALL_UPPER()}) {
  236. if (std::regex_match(word, regex)) return 2;
  237. }
  238. // otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters
  239. diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp
  240. index ec9fd22d8e18..1038ee34587c 100644
  241. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp
  242. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/scoring.hpp
  243. @@ -11,10 +11,10 @@
  244. namespace zxcvbn {
  245. -const auto START_UPPER = std::regex(R"(^[A-Z][^A-Z]+$)");
  246. -const auto END_UPPER = std::regex(R"(^[^A-Z]+[A-Z]$)");
  247. -const auto ALL_UPPER = std::regex(R"(^[^a-z]+$)");
  248. -const auto ALL_LOWER = std::regex(R"(^[^A-Z]+$)");
  249. +const std::regex& START_UPPER();
  250. +const std::regex& END_UPPER();
  251. +const std::regex& ALL_UPPER();
  252. +const std::regex& ALL_LOWER();
  253. const guesses_t MIN_YEAR_SPACE = 20;
  254. const auto REFERENCE_YEAR = 2016;
  255. diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
  256. index 084d3cc0cd7c..107bce0af064 100644
  257. --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
  258. +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
  259. @@ -8,6 +8,8 @@
  260. #include <cassert>
  261. +#include "base/no_destructor.h"
  262. +
  263. namespace zxcvbn {
  264. namespace util {
  265. @@ -32,7 +34,10 @@ std::string reverse_string(const std::string & in) {
  266. return conv.to_bytes(ret);
  267. }
  268. -const std::codecvt_utf8<char32_t> char32_conv;
  269. +const std::codecvt_utf8<char32_t>& char32_conv() {
  270. + static base::NoDestructor<std::codecvt_utf8<char32_t>> char32_conv;
  271. + return *char32_conv;
  272. +}
  273. bool utf8_valid(std::string::const_iterator start,
  274. std::string::const_iterator end) {
  275. @@ -46,8 +51,8 @@ bool utf8_valid(std::string::const_iterator start,
  276. char32_t new_char;
  277. char32_t *to_next;
  278. - auto res = char32_conv.in(st, from, from_end, from_next,
  279. - &new_char, &new_char + 1, to_next);
  280. + auto res = char32_conv().in(st, from, from_end, from_next, &new_char,
  281. + &new_char + 1, to_next);
  282. if (!((res == std::codecvt_utf8<char32_t>::result::partial &&
  283. from_next != from_end) ||
  284. (res == std::codecvt_utf8<char32_t>::result::ok &&
  285. @@ -67,7 +72,7 @@ template<class It>
  286. It _utf8_iter(It start, It end) {
  287. assert(start != end);
  288. std::mbstate_t st;
  289. - auto amt = char32_conv.length(st, &*start, &*end, 1);
  290. + auto amt = char32_conv().length(st, &*start, &*end, 1);
  291. return start + amt;
  292. }
  293. @@ -110,8 +115,8 @@ std::pair<char32_t, It> _utf8_decode(It it, It end) {
  294. const char *from = &*it;
  295. const char *from_end = &*end;
  296. const char *from_next;
  297. - auto res = char32_conv.in(st, from, from_end, from_next,
  298. - &new_char, &new_char + 1, to_next);
  299. + auto res = char32_conv().in(st, from, from_end, from_next, &new_char,
  300. + &new_char + 1, to_next);
  301. assert((res == std::codecvt_utf8<char32_t>::result::partial &&
  302. from_next != from_end) ||
  303. (res == std::codecvt_utf8<char32_t>::result::ok &&