| diff --git a/third_party/zxcvbn-cpp/data-scripts/build_keyboard_adjacency_graphs.py b/third_party/zxcvbn-cpp/data-scripts/build_keyboard_adjacency_graphs.py |
| index 8135c697ed2f..605f2d6d18bd 100755 |
| --- a/third_party/zxcvbn-cpp/data-scripts/build_keyboard_adjacency_graphs.py |
| +++ b/third_party/zxcvbn-cpp/data-scripts/build_keyboard_adjacency_graphs.py |
| @@ -90,6 +90,14 @@ def build_graph(layout_str, slanted): |
| adjacency_graph[char].append(position_table.get(coord, None)) |
| return adjacency_graph |
| |
| +# on qwerty, 'g' has degree 6, being adjacent to 'ftyhbv'. '\' has degree 1. |
| +# this calculates the average over all keys. |
| +def calc_average_deg_and_len(layout_str, slanted): |
| + graph = build_graph(layout_str, slanted) |
| + count = sum(a is not None for adj in graph.values() for a in adj) |
| + length = len(graph) |
| + return float(count) / length, length |
| + |
| GRAPHS = [('qwerty', (qwerty, True)), |
| ('dvorak', (dvorak, True)), |
| ('keypad', (keypad, False)), |
| @@ -127,6 +135,8 @@ def output_hpp(hpp_file): |
| #include <utility> |
| #include <vector> |
| |
| +#include "base/strings/string_piece.h" |
| + |
| namespace zxcvbn { |
| |
| enum class GraphTag { |
| @@ -148,7 +158,7 @@ struct hash<zxcvbn::GraphTag> { |
| |
| namespace zxcvbn { |
| |
| -using Graph = std::unordered_map<std::string, std::vector<optional::optional<std::string>>>; |
| +using Graph = std::unordered_map<base::StringPiece, std::vector<base::StringPiece>, base::StringPieceHash>; |
| using Graphs = std::unordered_map<GraphTag, Graph>; |
| const Graphs & graphs(); |
| |
| @@ -167,71 +177,47 @@ extern const std::size_t KEYPAD_STARTING_POSITIONS; |
| |
| def output_cpp(cpp_file): |
| with open(cpp_file, 'w') as f: |
| - f.write('// generated by scripts/build_keyboard_adjacency_graphs.py\n') |
| - f.write("#include <zxcvbn/adjacency_graphs.hpp>\n\n") |
| - f.write("#include <zxcvbn/optional.hpp>\n\n") |
| - f.write("#include <array>\n") |
| - f.write("#include <initializer_list>\n") |
| - f.write("#include <utility>\n\n") |
| + f.write("""// generated by scripts/build_keyboard_adjacency_graphs.py |
| +#include <zxcvbn/adjacency_graphs.hpp> |
| |
| - # find out largest adjacency_list |
| - largest = max(len(adj) |
| - for (_, args2) in GRAPHS |
| - for adj in build_graph(*args2).values()) |
| +#include <array> |
| +#include <initializer_list> |
| +#include <utility> |
| |
| +#include "base/no_destructor.h" |
| + |
| +""") |
| + |
| + qwerty_avg_deg, qwerty_len = calc_average_deg_and_len(qwerty, True) |
| + keypad_avg_deg, keypad_len = calc_average_deg_and_len(keypad, False) |
| f.write("""namespace zxcvbn { |
| |
| -static |
| -optional::optional<std::string> M(const char *s) { |
| - return optional::make_optional(std::string(s)); |
| -} |
| +extern constexpr degree_t KEYBOARD_AVERAGE_DEGREE = %f; |
| +// slightly different for keypad/mac keypad, but close enough |
| +extern constexpr degree_t KEYPAD_AVERAGE_DEGREE = %f; |
| |
| -const auto no = optional::nullopt; |
| +extern constexpr std::size_t KEYBOARD_STARTING_POSITIONS = %d; |
| +extern constexpr std::size_t KEYPAD_STARTING_POSITIONS = %d; |
| |
| -""") |
| +""" % (qwerty_avg_deg, keypad_avg_deg, qwerty_len, keypad_len)) |
| |
| - f.write("const Graphs _graphs = {\n") |
| + f.write("const Graphs& graphs() {\n") |
| + f.write(" static base::NoDestructor<Graphs> graphs({\n") |
| for (name, args2) in GRAPHS: |
| graph = build_graph(*args2) |
| |
| - f.write(" {GraphTag::%s, {\n" % (name.upper(),)); |
| + f.write(" {GraphTag::%s, {\n" % (name.upper(),)); |
| |
| for key, adj in sorted(graph.items()): |
| - f.write(' {"%s", {%s}},\n' % |
| - (escape(key), ', '.join('M("' + escape(a) + '")' |
| + f.write(' {"%s", {%s}},\n' % |
| + (escape(key), ', '.join('"' + escape(a) + '"' |
| if a else |
| - 'no' |
| + '{}' |
| for a in adj))) |
| - f.write(" }},\n") |
| - |
| - f.write("""}; |
| - |
| -// on qwerty, 'g' has degree 6, being adjacent to 'ftyhbv'. '\' has degree 1. |
| -// this calculates the average over all keys. |
| -static |
| -degree_t calc_average_degree(const Graph & graph) { |
| - degree_t average = 0; |
| - for (const auto & item : graph) { |
| - for (const auto & neighbor : item.second) { |
| - average += neighbor ? 1 : 0; |
| - } |
| - } |
| - average /= graph.size(); |
| - return average; |
| -} |
| - |
| -extern const degree_t KEYBOARD_AVERAGE_DEGREE = calc_average_degree(_graphs.at(GraphTag::QWERTY)); |
| -// slightly different for keypad/mac keypad, but close enough |
| -extern const degree_t KEYPAD_AVERAGE_DEGREE = calc_average_degree(_graphs.at(GraphTag::KEYPAD)); |
| - |
| -extern const std::size_t KEYBOARD_STARTING_POSITIONS = _graphs.at(GraphTag::QWERTY).size(); |
| -extern const std::size_t KEYPAD_STARTING_POSITIONS = _graphs.at(GraphTag::KEYPAD).size(); |
| - |
| -const Graphs & graphs() { |
| - return _graphs; |
| -} |
| - |
| -""") |
| + f.write(" }},\n") |
| + f.write(" });\n\n") |
| + f.write(" return *graphs;\n") |
| + f.write("}\n\n") |
| f.write("}\n") |
| |
| |
| diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp |
| index 173382e70626..c14e02618ec2 100644 |
| --- a/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp |
| +++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/matching.cpp |
| @@ -381,7 +381,7 @@ std::vector<Match> spatial_match_helper(const std::string & password, |
| if (it != graph.end()) { |
| return it->second; |
| } |
| - return std::vector<optional::optional<std::string>>(); |
| + return Graph::mapped_type(); |
| }(); |
| // consider growing pattern by one character if j hasn't gone over the edge. |
| if (j < clen) { |
| @@ -390,10 +390,10 @@ std::vector<Match> spatial_match_helper(const std::string & password, |
| auto cur_char = password.substr(jdx, next_jdx - jdx); |
| for (auto & adj : adjacents) { |
| cur_direction += 1; |
| - if (adj && adj->find(cur_char) != adj->npos) { |
| + if (adj.find(cur_char) != adj.npos) { |
| found = true; |
| found_direction = cur_direction; |
| - if (adj->find(cur_char) == 1) { |
| + if (adj.find(cur_char) == 1) { |
| // index 1 in the adjacency means the key is shifted, |
| // 0 means unshifted: A vs a, % vs 5, etc. |
| // for example, 'q' is adjacent to the entry '2@'. |