Index: third_party/WebKit/Source/core/frame/csp/CSPSource.cpp |
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp b/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp |
index 6dafec99436214fcd35176f28a55b14d67b5846c..7f0c996d3c07a1c0916cf6823e63247a6db605df 100644 |
--- a/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp |
+++ b/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp |
@@ -104,10 +104,94 @@ bool CSPSource::portMatches(int port, const String& protocol) const { |
return false; |
} |
+bool CSPSource::isSimilar(CSPSource* other) { |
+ bool schemesMatch = |
+ schemeMatches(other->m_scheme) || other->schemeMatches(m_scheme); |
+ if (!schemesMatch || isSchemeOnly() || other->isSchemeOnly()) |
+ return schemesMatch; |
+ bool hostsMatch = (m_host == other->m_host) || hostMatches(other->m_host) || |
+ other->hostMatches(m_host); |
+ bool portsMatch = (other->m_portWildcard == HasWildcard) || |
+ portMatches(other->m_port, other->m_scheme); |
+ bool pathsMatch = pathMatches(other->m_path) || other->pathMatches(m_path); |
+ if (hostsMatch && portsMatch && pathsMatch) |
+ return true; |
+ |
+ return false; |
+} |
+ |
+CSPSource* CSPSource::getCommon(CSPSource* other) { |
+ if (!isSimilar(other)) |
+ return nullptr; |
+ |
+ String scheme = isSchemeSubsumedBy(other) ? m_scheme : other->m_scheme; |
+ String host = (m_hostWildcard == HasWildcard) ? other->m_host : m_host; |
+ String path = isPathSubsumedBy(other) ? m_path : other->m_path; |
+ int port = isPortSubsumedBy(other) ? m_port : other->m_port; |
+ WildcardDisposition hostWildcard = |
+ (m_hostWildcard == HasWildcard) ? other->m_hostWildcard : m_hostWildcard; |
+ WildcardDisposition portWildcard = |
+ (m_portWildcard == HasWildcard) ? other->m_portWildcard : m_portWildcard; |
+ return new CSPSource(m_policy, scheme, host, port, path, hostWildcard, |
+ portWildcard); |
+} |
+ |
+bool CSPSource::isSubsumedBy(CSPSource* other) { |
+ if (!isSimilar(other) || !isSchemeSubsumedBy(other) || |
+ !isWildcardsSubsumedBy(other) || !isPortSubsumedBy(other) || |
+ !isPathSubsumedBy(other)) |
+ return false; |
+ |
+ return true; |
+} |
+ |
+bool CSPSource::isWildcardsSubsumedBy(CSPSource* other) { |
+ if ((m_hostWildcard == HasWildcard && other->m_hostWildcard == NoWildcard) || |
+ (m_portWildcard == HasWildcard && other->m_portWildcard == NoWildcard)) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+bool CSPSource::isSchemeSubsumedBy(CSPSource* other) { |
+ if (other->isSchemeOnly()) { |
+ if (other->m_scheme.length() == m_scheme.length()) |
+ return true; |
+ return m_scheme.length() == 3 || m_scheme.length() == 5 ? true : false; |
+ } |
+ if (isSchemeOnly()) |
+ return false; |
+ |
+ if (m_scheme.length() == other->m_scheme.length()) |
+ return true; |
+ |
+ // If the schemes match but their lengths are not equal, that means one of the |
+ // schemes is 'https' or 'wss' and the other one is 'http' or 'ws'. |
+ return m_scheme.length() > 3 ? (m_scheme == "https") : (m_scheme == "wss"); |
+} |
+ |
+bool CSPSource::isPortSubsumedBy(CSPSource* other) { |
+ bool otherIsMoreRestrictive = |
+ (other->m_portWildcard == NoWildcard) && (!m_port && other->m_port); |
+ return !otherIsMoreRestrictive; |
+} |
+ |
+bool CSPSource::isPathSubsumedBy(CSPSource* other) { |
+ bool otherIsMoreRestrictive = |
+ (isPathEmptyOrSlashOnly() && !other->isPathEmptyOrSlashOnly()) || |
+ (!isPathEmptyOrSlashOnly() && m_path.endsWith("/") && |
+ !other->m_path.endsWith("/")); |
+ return !otherIsMoreRestrictive; |
+} |
+ |
bool CSPSource::isSchemeOnly() const { |
return m_host.isEmpty(); |
} |
+bool CSPSource::isPathEmptyOrSlashOnly() const { |
+ return m_path.isEmpty() || m_path == "/"; |
+} |
+ |
DEFINE_TRACE(CSPSource) { |
visitor->trace(m_policy); |
} |