Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: components/ssl_errors/error_classification.cc

Issue 1690593002: Reduce memory use of GetLevenshteinDistance() by almost 50% (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: compile? Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ssl_errors/error_classification.h" 5 #include "components/ssl_errors/error_classification.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <vector> 10 #include <vector>
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { 60 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) {
61 if (overridable) { 61 if (overridable) {
62 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, 62 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event,
63 UNUSED_INTERSTITIAL_CAUSE_ENTRY); 63 UNUSED_INTERSTITIAL_CAUSE_ENTRY);
64 } else { 64 } else {
65 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, 65 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event,
66 UNUSED_INTERSTITIAL_CAUSE_ENTRY); 66 UNUSED_INTERSTITIAL_CAUSE_ENTRY);
67 } 67 }
68 } 68 }
69 69
70 // Returns the Levenshtein distance between |str1| and |str2|.
71 // Which is the minimum number of single-character edits (i.e. insertions,
72 // deletions or substitutions) required to change one word into the other.
73 // https://en.wikipedia.org/wiki/Levenshtein_distance
74 size_t GetLevenshteinDistance(const std::string& str1,
75 const std::string& str2) {
76 if (str1 == str2)
77 return 0;
78 if (str1.size() == 0)
79 return str2.size();
80 if (str2.size() == 0)
81 return str1.size();
82 std::vector<size_t> kFirstRow(str2.size() + 1, 0);
83 std::vector<size_t> kSecondRow(str2.size() + 1, 0);
84
85 for (size_t i = 0; i < kFirstRow.size(); ++i)
86 kFirstRow[i] = i;
87 for (size_t i = 0; i < str1.size(); ++i) {
88 kSecondRow[0] = i + 1;
89 for (size_t j = 0; j < str2.size(); ++j) {
90 int cost = str1[i] == str2[j] ? 0 : 1;
91 kSecondRow[j + 1] =
92 std::min(std::min(kSecondRow[j] + 1, kFirstRow[j + 1] + 1),
93 kFirstRow[j] + cost);
94 }
95 for (size_t j = 0; j < kFirstRow.size(); j++)
96 kFirstRow[j] = kSecondRow[j];
97 }
98 return kSecondRow[str2.size()];
99 }
100
101 std::vector<HostnameTokens> GetTokenizedDNSNames( 70 std::vector<HostnameTokens> GetTokenizedDNSNames(
102 const std::vector<std::string>& dns_names) { 71 const std::vector<std::string>& dns_names) {
103 std::vector<HostnameTokens> dns_name_tokens; 72 std::vector<HostnameTokens> dns_name_tokens;
104 for (const auto& dns_name : dns_names) { 73 for (const auto& dns_name : dns_names) {
105 HostnameTokens dns_name_token_single; 74 HostnameTokens dns_name_token_single;
106 if (dns_name.empty() || dns_name.find('\0') != std::string::npos || 75 if (dns_name.empty() || dns_name.find('\0') != std::string::npos ||
107 !(IsHostNameKnownTLD(dns_name))) { 76 !(IsHostNameKnownTLD(dns_name))) {
108 dns_name_token_single.push_back(std::string()); 77 dns_name_token_single.push_back(std::string());
109 } else { 78 } else {
110 dns_name_token_single = Tokenize(dns_name); 79 dns_name_token_single = Tokenize(dns_name);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 std::vector<std::string> dns_names; 111 std::vector<std::string> dns_names;
143 cert.GetDNSNames(&dns_names); 112 cert.GetDNSNames(&dns_names);
144 return GetWWWSubDomainMatch(request_url, dns_names, &www_host); 113 return GetWWWSubDomainMatch(request_url, dns_names, &www_host);
145 } 114 }
146 115
147 // The time to use when doing build time operations in browser tests. 116 // The time to use when doing build time operations in browser tests.
148 base::LazyInstance<base::Time> g_testing_build_time = LAZY_INSTANCE_INITIALIZER; 117 base::LazyInstance<base::Time> g_testing_build_time = LAZY_INSTANCE_INITIALIZER;
149 118
150 } // namespace 119 } // namespace
151 120
121 // Returns the Levenshtein distance between |str1| and |str2|.
122 // Which is the minimum number of single-character edits (i.e. insertions,
123 // deletions or substitutions) required to change one word into the other.
124 // https://en.wikipedia.org/wiki/Levenshtein_distance
125 size_t GetLevenshteinDistance(const std::string& str1,
126 const std::string& str2) {
127 if (str1 == str2)
128 return 0;
129 if (str1.size() == 0)
130 return str2.size();
131 if (str2.size() == 0)
132 return str1.size();
133
134 std::vector<size_t> row(str2.size() + 1);
135 for (size_t i = 0; i < row.size(); ++i)
136 row[i] = i;
137
138 for (size_t i = 0; i < str1.size(); ++i) {
139 row[0] = i + 1;
140 size_t previous = i;
141 for (size_t j = 0; j < str2.size(); ++j) {
142 size_t old_row = row[j + 1];
143 int cost = str1[i] == str2[j] ? 0 : 1;
144 row[j + 1] = std::min(std::min(row[j], row[j + 1]) + 1, previous + cost);
145 previous = old_row;
146 }
147 }
148 return row[str2.size()];
149 }
150
151
152 void RecordUMAStatistics(bool overridable, 152 void RecordUMAStatistics(bool overridable,
153 const base::Time& current_time, 153 const base::Time& current_time,
154 const GURL& request_url, 154 const GURL& request_url,
155 int cert_error, 155 int cert_error,
156 const net::X509Certificate& cert) { 156 const net::X509Certificate& cert) {
157 ssl_errors::ErrorInfo::ErrorType type = 157 ssl_errors::ErrorInfo::ErrorType type =
158 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error); 158 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error);
159 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type, 159 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type,
160 ssl_errors::ErrorInfo::END_OF_ENUM); 160 ssl_errors::ErrorInfo::END_OF_ENUM);
161 switch (type) { 161 switch (type) {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 static const int kDistinctNameThreshold = 5; 381 static const int kDistinctNameThreshold = 5;
382 if (dns_names_size > kDistinctNameThreshold) 382 if (dns_names_size > kDistinctNameThreshold)
383 return true; 383 return true;
384 384
385 // Heuristic - The edit distance between all the strings should be at least 5 385 // Heuristic - The edit distance between all the strings should be at least 5
386 // for it to be counted as a shared SSLCertificate. If even one pair of 386 // for it to be counted as a shared SSLCertificate. If even one pair of
387 // strings edit distance is below 5 then the certificate is no longer 387 // strings edit distance is below 5 then the certificate is no longer
388 // considered as a shared certificate. Include the host name in the URL also 388 // considered as a shared certificate. Include the host name in the URL also
389 // while comparing. 389 // while comparing.
390 dns_names.push_back(host_name); 390 dns_names.push_back(host_name);
391 static const size_t kMinimumEditDsitance = 5; 391 static const size_t kMinimumEditDistance = 5;
392 for (size_t i = 0; i < dns_names_size; ++i) { 392 for (size_t i = 0; i < dns_names_size; ++i) {
393 for (size_t j = i + 1; j < dns_names_size; ++j) { 393 for (size_t j = i + 1; j < dns_names_size; ++j) {
394 size_t edit_distance = GetLevenshteinDistance(dns_names[i], dns_names[j]); 394 size_t edit_distance = GetLevenshteinDistance(dns_names[i], dns_names[j]);
395 if (edit_distance < kMinimumEditDsitance) 395 if (edit_distance < kMinimumEditDistance)
396 return false; 396 return false;
397 } 397 }
398 } 398 }
399 return true; 399 return true;
400 } 400 }
401 401
402 bool IsCertLikelyFromSameDomain(const GURL& request_url, 402 bool IsCertLikelyFromSameDomain(const GURL& request_url,
403 const net::X509Certificate& cert) { 403 const net::X509Certificate& cert) {
404 std::string host_name = request_url.host(); 404 std::string host_name = request_url.host();
405 std::vector<std::string> dns_names; 405 std::vector<std::string> dns_names;
(...skipping 16 matching lines...) Expand all
422 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1, 422 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1,
423 host_name_domain) != dns_names_domain.end() - 1; 423 host_name_domain) != dns_names_domain.end() - 1;
424 } 424 }
425 425
426 bool IsHostnameNonUniqueOrDotless(const std::string& hostname) { 426 bool IsHostnameNonUniqueOrDotless(const std::string& hostname) {
427 return net::IsHostnameNonUnique(hostname) || 427 return net::IsHostnameNonUnique(hostname) ||
428 hostname.find('.') == std::string::npos; 428 hostname.find('.') == std::string::npos;
429 } 429 }
430 430
431 } // namespace ssl_errors 431 } // namespace ssl_errors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698