blob: 7774fdb0b095518bb25d036e244e713f778fac2c [file] [log] [blame]
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@'.