CSPSource* CSPSource::intersect(CSPSource* other) const { if (!isSimilar(other)) return nullptr; String scheme = other->schemeMatches(m_scheme) ? m_scheme : other->m_scheme; if (isSchemeOnly() || other->isSchemeOnly()) { const CSPSource* stricter = isSchemeOnly() ? other : this; return new CSPSource(m_policy, scheme, stricter->m_host, stricter->m_port, stricter->m_path, stricter->m_hostWildcard, stricter->m_portWildcard); } String host = m_hostWildcard == NoWildcard ? m_host : other->m_host; // Since sources are similar and paths match, pick the longer one. String path = m_path.length() > other->m_path.length() ? m_path : other->m_path; // Choose this port if the other port is empty, has wildcard or is a port for // a less secure scheme such as "http" whereas scheme of this is "https", in // which case the lengths would differ. int port = (other->m_portWildcard == HasWildcard || !other->m_port || m_scheme.length() > other->m_scheme.length()) ? 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 matches(const KURL& url) const { if (!schemeMatches(url)) return false; if (isSchemeOnly()) return true; return hostMatches(url) && portMatches(url); }
bool CSPSource::matches(const KURL& url, ContentSecurityPolicy::RedirectStatus redirectStatus) const { if (!schemeMatches(url)) return false; if (isSchemeOnly()) return true; bool pathsMatch = (redirectStatus == ContentSecurityPolicy::DidRedirect) || pathMatches(url); return hostMatches(url) && portMatches(url) && pathsMatch; }
bool CSPSource::subsumes(CSPSource* other) const { if (!schemeMatches(other->m_scheme)) return false; if (other->isSchemeOnly() || isSchemeOnly()) return isSchemeOnly(); if ((m_hostWildcard == NoWildcard && other->m_hostWildcard == HasWildcard) || (m_portWildcard == NoWildcard && other->m_portWildcard == HasWildcard)) { return false; } bool hostSubsumes = (m_host == other->m_host || hostMatches(other->m_host)); bool portSubsumes = (m_portWildcard == HasWildcard) || portMatches(other->m_port, other->m_scheme); bool pathSubsumes = pathMatches(other->m_path); return hostSubsumes && portSubsumes && pathSubsumes; }
bool CSPSource::matches(const KURL& url, ResourceRequest::RedirectStatus redirectStatus) const { bool schemesMatch = m_scheme.isEmpty() ? m_policy->protocolMatchesSelf(url) : schemeMatches(url.protocol()); if (!schemesMatch) return false; if (isSchemeOnly()) return true; bool pathsMatch = (redirectStatus == RedirectStatus::FollowedRedirect) || pathMatches(url.path()); return hostMatches(url.host()) && portMatches(url.port(), url.protocol()) && pathsMatch; }
bool CSPSource::isSimilar(CSPSource* other) const { 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) || other->portMatches(m_port, m_scheme); bool pathsMatch = pathMatches(other->m_path) || other->pathMatches(m_path); if (hostsMatch && portsMatch && pathsMatch) return true; return false; }