Index: components/password_manager/core/browser/affiliation_utils.cc |
diff --git a/components/password_manager/core/browser/affiliation_utils.cc b/components/password_manager/core/browser/affiliation_utils.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a1f5eeb4c8715c0b3e5d76420e909d253bbeb8f0 |
--- /dev/null |
+++ b/components/password_manager/core/browser/affiliation_utils.cc |
@@ -0,0 +1,60 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/password_manager/core/browser/affiliation_utils.h" |
+ |
+#include "base/strings/string_util.h" |
+#include "url/gurl.h" |
+#include "url/third_party/mozilla/url_parse.h" |
+ |
+namespace password_manager { |
+ |
+const char kAndroidAppScheme[] = "android"; |
+ |
+bool IsValidFacetURI(const std::string& uri) { |
+ return IsValidWebFacetURI(uri) || IsValidAndroidFacetURI(uri); |
+} |
+ |
+bool IsValidWebFacetURI(const std::string& uri) { |
+ url::Parsed url_parsed; |
+ url::ParseStandardURL(uri.c_str(), uri.size(), &url_parsed); |
+ return url_parsed.scheme.is_nonempty() && |
+ LowerCaseEqualsASCII(&uri[url_parsed.scheme.begin], |
+ &uri[url_parsed.scheme.end()], |
+ url::kHttpsScheme) && |
+ !url_parsed.username.is_valid() && !url_parsed.password.is_valid() && |
+ url_parsed.host.is_nonempty() && url_parsed.path.is_nonempty() && |
+ url_parsed.path.len == 1 && uri[url_parsed.path.begin] == '/' && |
+ !url_parsed.query.is_valid() && !url_parsed.ref.is_valid(); |
+} |
+ |
+bool IsValidAndroidFacetURI(const std::string& uri) { |
+ // Treat URIs with the "android" scheme as standard URLs, so the APK hash will |
+ // be treated as a username. |
+ url::Parsed url_parsed; |
+ url::ParseStandardURL(uri.c_str(), uri.size(), &url_parsed); |
+ return url_parsed.scheme.is_nonempty() && |
+ LowerCaseEqualsASCII(&uri[url_parsed.scheme.begin], |
+ &uri[url_parsed.scheme.end()], |
+ kAndroidAppScheme) && |
+ url_parsed.username.is_nonempty() && !url_parsed.password.is_valid() && |
+ url_parsed.host.is_nonempty() && !url_parsed.port.is_valid() && |
+ url_parsed.path.is_nonempty() && url_parsed.path.len == 1 && |
+ uri[url_parsed.path.begin] == '/' && !url_parsed.query.is_valid() && |
+ !url_parsed.ref.is_valid(); |
+} |
+ |
+bool AreEquivalenceClassesEqual(const AffiliatedFacets& a, |
+ const AffiliatedFacets& b) { |
+ if (a.size() != b.size()) |
+ return false; |
+ |
+ std::vector<std::string> a_sorted(a.begin(), a.end()); |
+ std::vector<std::string> b_sorted(b.begin(), b.end()); |
+ std::sort(a_sorted.begin(), a_sorted.end()); |
+ std::sort(b_sorted.begin(), b_sorted.end()); |
+ return std::equal(a_sorted.begin(), a_sorted.end(), b_sorted.begin()); |
+} |
+ |
+} // namespace password_manager |