Commit 0ba1b246 authored by David Van Cleve's avatar David Van Cleve Committed by Commit Bot

CSP: Distinguish port 0 from a default or empty port

The CSP data structures in Blink currently use a value of 0 to denote an
unspecified or default-valued port in CSP source expressions. However,
origins can also have ports explicitly set to 0.

In order to resolve behavior inconsistencies between
blink::SecurityOrigin, which currently doesn't support port 0, and
url::Origin, which does, we're updating blink::SecurityOrigin to
distinguish port-0 origins from origins with unspecified
(default-valued) ports. This makes SourceListDirectiveTest.GetSources
CSP tests fail, because it means that a "self" CSPSource created by
ContentSecurityPolicy::SetupSelf from an origin with the default port
will no longer have the same port as a CSPSource created by parsing a
host-source source expression with no port.

To fix this, we update CSPSource's port_ member to have a new default
state denoting an unspecified or default-valued port, distinct from the
value 0 which now specifically represents port 0.

Bug: 1136678
Change-Id: Ic386fc2ba31e13c95676ecf050e24874d4af132e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2477044
Commit-Queue: David Van Cleve <davidvc@chromium.org>
Reviewed-by: default avatarAndy Paicu <andypaicu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#823558}
parent 6965e0b1
...@@ -180,7 +180,17 @@ void ContentSecurityPolicy::SetupSelf(const SecurityOrigin& security_origin) { ...@@ -180,7 +180,17 @@ void ContentSecurityPolicy::SetupSelf(const SecurityOrigin& security_origin) {
// Ensure that 'self' processes correctly. // Ensure that 'self' processes correctly.
self_protocol_ = security_origin.Protocol(); self_protocol_ = security_origin.Protocol();
self_source_ = MakeGarbageCollected<CSPSource>( self_source_ = MakeGarbageCollected<CSPSource>(
this, self_protocol_, security_origin.Host(), security_origin.Port(), this, self_protocol_, security_origin.Host(),
// CSPSource uses port CSPSource::kPortUnspecified to represent a
// missing port and reserves port 0 specifically for origins with port set
// to 0; SecurityOrigin uses port 0 for origins with port 0 as well as for
// origins without ports.
//
// TODO(crbug.com/1136678): Once SecurityOrigin starts treating port 0 as
// a specifically set port, rather than as a sentinel for an
// omitted or default-valued port, modify this logic.
security_origin.Port() == 0 ? CSPSource::kPortUnspecified
: security_origin.Port(),
String(), CSPSource::kNoWildcard, CSPSource::kNoWildcard); String(), CSPSource::kNoWildcard, CSPSource::kNoWildcard);
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
namespace blink { namespace blink {
constexpr int CSPSource::kPortUnspecified = -1;
CSPSource::CSPSource(ContentSecurityPolicy* policy, CSPSource::CSPSource(ContentSecurityPolicy* policy,
const String& scheme, const String& scheme,
const String& host, const String& host,
...@@ -48,7 +50,8 @@ bool CSPSource::Matches(const KURL& url, ...@@ -48,7 +50,8 @@ bool CSPSource::Matches(const KURL& url,
return true; return true;
bool paths_match = (redirect_status == RedirectStatus::kFollowedRedirect) || bool paths_match = (redirect_status == RedirectStatus::kFollowedRedirect) ||
PathMatches(url.GetPath()); PathMatches(url.GetPath());
PortMatchingResult ports_match = PortMatches(url.Port(), url.Protocol()); PortMatchingResult ports_match = PortMatches(
url.HasPort() ? url.Port() : kPortUnspecified, url.Protocol());
// if either the scheme or the port would require an upgrade (e.g. from http // if either the scheme or the port would require an upgrade (e.g. from http
// to https) then check that both of them can upgrade to ensure that we don't // to https) then check that both of them can upgrade to ensure that we don't
...@@ -68,7 +71,8 @@ bool CSPSource::MatchesAsSelf(const KURL& url) { ...@@ -68,7 +71,8 @@ bool CSPSource::MatchesAsSelf(const KURL& url) {
// Step 4. // Step 4.
SchemeMatchingResult schemes_match = SchemeMatches(url.Protocol()); SchemeMatchingResult schemes_match = SchemeMatches(url.Protocol());
bool hosts_match = HostMatches(url.Host()); bool hosts_match = HostMatches(url.Host());
PortMatchingResult ports_match = PortMatches(url.Port(), url.Protocol()); PortMatchingResult ports_match = PortMatches(
url.HasPort() ? url.Port() : kPortUnspecified, url.Protocol());
// check if the origin is exactly matching // check if the origin is exactly matching
if (schemes_match == SchemeMatchingResult::kMatchingExact && hosts_match && if (schemes_match == SchemeMatchingResult::kMatchingExact && hosts_match &&
...@@ -82,9 +86,10 @@ bool CSPSource::MatchesAsSelf(const KURL& url) { ...@@ -82,9 +86,10 @@ bool CSPSource::MatchesAsSelf(const KURL& url) {
bool ports_match_or_defaults = bool ports_match_or_defaults =
(ports_match == PortMatchingResult::kMatchingExact || (ports_match == PortMatchingResult::kMatchingExact ||
((IsDefaultPortForProtocol(port_, self_scheme) || port_ == 0) && ((IsDefaultPortForProtocol(port_, self_scheme) ||
(IsDefaultPortForProtocol(url.Port(), url.Protocol()) || port_ == kPortUnspecified) &&
url.Port() == 0))); (!url.HasPort() ||
IsDefaultPortForProtocol(url.Port(), url.Protocol()))));
if (hosts_match && ports_match_or_defaults && if (hosts_match && ports_match_or_defaults &&
(url.Protocol() == "https" || url.Protocol() == "wss" || (url.Protocol() == "https" || url.Protocol() == "wss" ||
...@@ -159,7 +164,7 @@ CSPSource::PortMatchingResult CSPSource::PortMatches( ...@@ -159,7 +164,7 @@ CSPSource::PortMatchingResult CSPSource::PortMatches(
return PortMatchingResult::kMatchingWildcard; return PortMatchingResult::kMatchingWildcard;
if (port == port_) { if (port == port_) {
if (port == 0) if (port == kPortUnspecified)
return PortMatchingResult::kMatchingWildcard; return PortMatchingResult::kMatchingWildcard;
return PortMatchingResult::kMatchingExact; return PortMatchingResult::kMatchingExact;
} }
...@@ -168,18 +173,21 @@ CSPSource::PortMatchingResult CSPSource::PortMatches( ...@@ -168,18 +173,21 @@ CSPSource::PortMatchingResult CSPSource::PortMatches(
is_scheme_http = scheme_.IsEmpty() ? policy_->ProtocolEqualsSelf("http") is_scheme_http = scheme_.IsEmpty() ? policy_->ProtocolEqualsSelf("http")
: EqualIgnoringASCIICase("http", scheme_); : EqualIgnoringASCIICase("http", scheme_);
if ((port_ == 80 || ((port_ == 0 || port_ == 443) && is_scheme_http)) && if ((port_ == 80 ||
(port == 443 || (port == 0 && DefaultPortForProtocol(protocol) == 443))) ((port_ == kPortUnspecified || port_ == 443) && is_scheme_http)) &&
(port == 443 ||
(port == kPortUnspecified && DefaultPortForProtocol(protocol) == 443))) {
return PortMatchingResult::kMatchingUpgrade; return PortMatchingResult::kMatchingUpgrade;
}
if (!port) { if (port == kPortUnspecified) {
if (IsDefaultPortForProtocol(port_, protocol)) if (IsDefaultPortForProtocol(port_, protocol))
return PortMatchingResult::kMatchingExact; return PortMatchingResult::kMatchingExact;
return PortMatchingResult::kNotMatching; return PortMatchingResult::kNotMatching;
} }
if (!port_) { if (port_ == kPortUnspecified) {
if (IsDefaultPortForProtocol(port, protocol)) if (IsDefaultPortForProtocol(port, protocol))
return PortMatchingResult::kMatchingExact; return PortMatchingResult::kMatchingExact;
...@@ -261,7 +269,8 @@ CSPSource* CSPSource::Intersect(CSPSource* other) const { ...@@ -261,7 +269,8 @@ CSPSource* CSPSource::Intersect(CSPSource* other) const {
// Choose this port if the other port is empty, has wildcard or is a port for // 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 // a less secure scheme such as "http" whereas scheme of this is "https", in
// which case the lengths would differ. // which case the lengths would differ.
int port = (other->port_wildcard_ == kHasWildcard || !other->port_ || int port = (other->port_wildcard_ == kHasWildcard ||
other->port_ == kPortUnspecified ||
scheme_.length() > other->scheme_.length()) scheme_.length() > other->scheme_.length())
? port_ ? port_
: other->port_; : other->port_;
...@@ -302,12 +311,13 @@ bool CSPSource::FirstSubsumesSecond( ...@@ -302,12 +311,13 @@ bool CSPSource::FirstSubsumesSecond(
network::mojom::blink::CSPSourcePtr CSPSource::ExposeForNavigationalChecks() network::mojom::blink::CSPSourcePtr CSPSource::ExposeForNavigationalChecks()
const { const {
return network::mojom::blink::CSPSource::New( return network::mojom::blink::CSPSource::New(
scheme_ ? scheme_ : "", // scheme scheme_ ? scheme_ : "", // scheme
host_ ? host_ : "", // host host_ ? host_ : "", // host
port_ == 0 ? -1 /* url::PORT_UNSPECIFIED */ : port_, // port port_ == kPortUnspecified ? -1 /* url::PORT_UNSPECIFIED */
path_ ? path_ : "", // path : port_, // port
host_wildcard_ == kHasWildcard, // is_host_wildcard path_ ? path_ : "", // path
port_wildcard_ == kHasWildcard // is_port_wildcard host_wildcard_ == kHasWildcard, // is_host_wildcard
port_wildcard_ == kHasWildcard // is_port_wildcard
); );
} }
......
...@@ -20,6 +20,9 @@ class KURL; ...@@ -20,6 +20,9 @@ class KURL;
class CORE_EXPORT CSPSource final : public GarbageCollected<CSPSource> { class CORE_EXPORT CSPSource final : public GarbageCollected<CSPSource> {
public: public:
// Represents the absence of a port.
const static int kPortUnspecified;
enum WildcardDisposition { kNoWildcard, kHasWildcard }; enum WildcardDisposition { kNoWildcard, kHasWildcard };
// NotMatching is the only negative member, the rest are different types of // NotMatching is the only negative member, the rest are different types of
......
...@@ -23,8 +23,8 @@ class CSPSourceTest : public testing::Test { ...@@ -23,8 +23,8 @@ class CSPSourceTest : public testing::Test {
String scheme; String scheme;
String host; String host;
String path; String path;
// port is 0 if it was not specified so the default port for a given scheme // port is CSPSource::kPortUnspecified if it was not specified so the
// will be used. // default port for a given scheme will be used.
const int port; const int port;
CSPSource::WildcardDisposition host_wildcard; CSPSource::WildcardDisposition host_wildcard;
CSPSource::WildcardDisposition port_wildcard; CSPSource::WildcardDisposition port_wildcard;
...@@ -77,8 +77,9 @@ TEST_F(CSPSourceTest, BasicPathMatching) { ...@@ -77,8 +77,9 @@ TEST_F(CSPSourceTest, BasicPathMatching) {
TEST_F(CSPSourceTest, WildcardMatching) { TEST_F(CSPSourceTest, WildcardMatching) {
KURL base; KURL base;
CSPSource source(csp.Get(), "http", "example.com", 0, "/", CSPSource source(csp.Get(), "http", "example.com",
CSPSource::kHasWildcard, CSPSource::kHasWildcard); CSPSource::kPortUnspecified, "/", CSPSource::kHasWildcard,
CSPSource::kHasWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://foo.example.com:8000/"))); EXPECT_TRUE(source.Matches(KURL(base, "http://foo.example.com:8000/")));
EXPECT_TRUE(source.Matches(KURL(base, "http://foo.example.com:8000/foo"))); EXPECT_TRUE(source.Matches(KURL(base, "http://foo.example.com:8000/foo")));
...@@ -118,8 +119,8 @@ TEST_F(CSPSourceTest, RedirectMatching) { ...@@ -118,8 +119,8 @@ TEST_F(CSPSourceTest, RedirectMatching) {
TEST_F(CSPSourceTest, InsecureSchemeMatchesSecureScheme) { TEST_F(CSPSourceTest, InsecureSchemeMatchesSecureScheme) {
KURL base; KURL base;
CSPSource source(csp.Get(), "http", "", 0, "/", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "http", "", CSPSource::kPortUnspecified, "/",
CSPSource::kHasWildcard); CSPSource::kNoWildcard, CSPSource::kHasWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://example.com:8000/"))); EXPECT_TRUE(source.Matches(KURL(base, "http://example.com:8000/")));
EXPECT_TRUE(source.Matches(KURL(base, "https://example.com:8000/"))); EXPECT_TRUE(source.Matches(KURL(base, "https://example.com:8000/")));
...@@ -130,8 +131,9 @@ TEST_F(CSPSourceTest, InsecureSchemeMatchesSecureScheme) { ...@@ -130,8 +131,9 @@ TEST_F(CSPSourceTest, InsecureSchemeMatchesSecureScheme) {
TEST_F(CSPSourceTest, InsecureHostSchemeMatchesSecureScheme) { TEST_F(CSPSourceTest, InsecureHostSchemeMatchesSecureScheme) {
KURL base; KURL base;
CSPSource source(csp.Get(), "http", "example.com", 0, "/", CSPSource source(csp.Get(), "http", "example.com",
CSPSource::kNoWildcard, CSPSource::kHasWildcard); CSPSource::kPortUnspecified, "/", CSPSource::kNoWildcard,
CSPSource::kHasWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://example.com:8000/"))); EXPECT_TRUE(source.Matches(KURL(base, "http://example.com:8000/")));
EXPECT_FALSE(source.Matches(KURL(base, "http://not-example.com:8000/"))); EXPECT_FALSE(source.Matches(KURL(base, "http://not-example.com:8000/")));
...@@ -147,8 +149,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) { ...@@ -147,8 +149,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) {
Persistent<ContentSecurityPolicy> csp( Persistent<ContentSecurityPolicy> csp(
MakeGarbageCollected<ContentSecurityPolicy>()); MakeGarbageCollected<ContentSecurityPolicy>());
csp->SetupSelf(*SecurityOrigin::CreateFromString("http://a.com/")); csp->SetupSelf(*SecurityOrigin::CreateFromString("http://a.com/"));
CSPSource source(csp.Get(), "", "a.com", 0, "/", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "", "a.com", CSPSource::kPortUnspecified, "/",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://a.com"))); EXPECT_TRUE(source.Matches(KURL(base, "http://a.com")));
EXPECT_TRUE(source.Matches(KURL(base, "https://a.com"))); EXPECT_TRUE(source.Matches(KURL(base, "https://a.com")));
EXPECT_FALSE(source.Matches(KURL(base, "ftp://a.com"))); EXPECT_FALSE(source.Matches(KURL(base, "ftp://a.com")));
...@@ -159,8 +161,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) { ...@@ -159,8 +161,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) {
Persistent<ContentSecurityPolicy> csp( Persistent<ContentSecurityPolicy> csp(
MakeGarbageCollected<ContentSecurityPolicy>()); MakeGarbageCollected<ContentSecurityPolicy>());
csp->SetupSelf(*SecurityOrigin::CreateFromString("https://a.com/")); csp->SetupSelf(*SecurityOrigin::CreateFromString("https://a.com/"));
CSPSource source(csp.Get(), "", "a.com", 0, "/", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "", "a.com", CSPSource::kPortUnspecified, "/",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_FALSE(source.Matches(KURL(base, "http://a.com"))); EXPECT_FALSE(source.Matches(KURL(base, "http://a.com")));
EXPECT_TRUE(source.Matches(KURL(base, "https://a.com"))); EXPECT_TRUE(source.Matches(KURL(base, "https://a.com")));
EXPECT_FALSE(source.Matches(KURL(base, "ftp://a.com"))); EXPECT_FALSE(source.Matches(KURL(base, "ftp://a.com")));
...@@ -171,8 +173,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) { ...@@ -171,8 +173,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) {
Persistent<ContentSecurityPolicy> csp( Persistent<ContentSecurityPolicy> csp(
MakeGarbageCollected<ContentSecurityPolicy>()); MakeGarbageCollected<ContentSecurityPolicy>());
csp->SetupSelf(*SecurityOrigin::CreateFromString("ftp://a.com/")); csp->SetupSelf(*SecurityOrigin::CreateFromString("ftp://a.com/"));
CSPSource source(csp.Get(), "", "a.com", 0, "/", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "", "a.com", CSPSource::kPortUnspecified, "/",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_FALSE(source.Matches(KURL(base, "http://a.com"))); EXPECT_FALSE(source.Matches(KURL(base, "http://a.com")));
EXPECT_TRUE(source.Matches(KURL(base, "ftp://a.com"))); EXPECT_TRUE(source.Matches(KURL(base, "ftp://a.com")));
} }
...@@ -183,8 +185,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) { ...@@ -183,8 +185,8 @@ TEST_F(CSPSourceTest, SchemeIsEmpty) {
MakeGarbageCollected<ContentSecurityPolicy>()); MakeGarbageCollected<ContentSecurityPolicy>());
csp->SetupSelf( csp->SetupSelf(
*SecurityOrigin::CreateFromString("non-standard-scheme://a.com/")); *SecurityOrigin::CreateFromString("non-standard-scheme://a.com/"));
CSPSource source(csp.Get(), "", "a.com", 0, "/", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "", "a.com", CSPSource::kPortUnspecified, "/",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_FALSE(source.Matches(KURL(base, "http://a.com"))); EXPECT_FALSE(source.Matches(KURL(base, "http://a.com")));
// The reason matching fails is because the host is parsed as "" when // The reason matching fails is because the host is parsed as "" when
...@@ -246,8 +248,9 @@ TEST_F(CSPSourceTest, InsecureHostSchemePortMatchesSecurePort) { ...@@ -246,8 +248,9 @@ TEST_F(CSPSourceTest, InsecureHostSchemePortMatchesSecurePort) {
// source port is empty // source port is empty
{ {
CSPSource source(csp.Get(), "http", "example.com", 0, "/", CSPSource source(csp.Get(), "http", "example.com",
CSPSource::kNoWildcard, CSPSource::kNoWildcard); CSPSource::kPortUnspecified, "/", CSPSource::kNoWildcard,
CSPSource::kNoWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://example.com"))); EXPECT_TRUE(source.Matches(KURL(base, "http://example.com")));
EXPECT_TRUE(source.Matches(KURL(base, "https://example.com"))); EXPECT_TRUE(source.Matches(KURL(base, "https://example.com")));
...@@ -266,16 +269,16 @@ TEST_F(CSPSourceTest, HostMatches) { ...@@ -266,16 +269,16 @@ TEST_F(CSPSourceTest, HostMatches) {
// Host is * (source-expression = "http://*") // Host is * (source-expression = "http://*")
{ {
CSPSource source(csp.Get(), "http", "", 0, "", CSPSource::kHasWildcard, CSPSource source(csp.Get(), "http", "", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kHasWildcard, CSPSource::kNoWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://a.com"))); EXPECT_TRUE(source.Matches(KURL(base, "http://a.com")));
EXPECT_TRUE(source.Matches(KURL(base, "http://."))); EXPECT_TRUE(source.Matches(KURL(base, "http://.")));
} }
// Host is *.foo.bar // Host is *.foo.bar
{ {
CSPSource source(csp.Get(), "", "foo.bar", 0, "", CSPSource::kHasWildcard, CSPSource source(csp.Get(), "", "foo.bar", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kHasWildcard, CSPSource::kNoWildcard);
EXPECT_FALSE(source.Matches(KURL(base, "http://a.com"))); EXPECT_FALSE(source.Matches(KURL(base, "http://a.com")));
EXPECT_FALSE(source.Matches(KURL(base, "http://bar"))); EXPECT_FALSE(source.Matches(KURL(base, "http://bar")));
EXPECT_FALSE(source.Matches(KURL(base, "http://foo.bar"))); EXPECT_FALSE(source.Matches(KURL(base, "http://foo.bar")));
...@@ -289,8 +292,8 @@ TEST_F(CSPSourceTest, HostMatches) { ...@@ -289,8 +292,8 @@ TEST_F(CSPSourceTest, HostMatches) {
// Host is exact. // Host is exact.
{ {
CSPSource source(csp.Get(), "", "foo.bar", 0, "", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "", "foo.bar", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://foo.bar"))); EXPECT_TRUE(source.Matches(KURL(base, "http://foo.bar")));
EXPECT_FALSE(source.Matches(KURL(base, "http://sub.foo.bar"))); EXPECT_FALSE(source.Matches(KURL(base, "http://sub.foo.bar")));
EXPECT_FALSE(source.Matches(KURL(base, "http://bar"))); EXPECT_FALSE(source.Matches(KURL(base, "http://bar")));
...@@ -300,16 +303,16 @@ TEST_F(CSPSourceTest, HostMatches) { ...@@ -300,16 +303,16 @@ TEST_F(CSPSourceTest, HostMatches) {
// Host matching is case-insensitive. // Host matching is case-insensitive.
{ {
CSPSource source(csp.Get(), "", "FoO.BaR", 0, "", CSPSource::kNoWildcard, CSPSource source(csp.Get(), "", "FoO.BaR", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://foo.bar"))); EXPECT_TRUE(source.Matches(KURL(base, "http://foo.bar")));
EXPECT_FALSE(source.Matches(KURL(base, "http://sub.foo.bar"))); EXPECT_FALSE(source.Matches(KURL(base, "http://sub.foo.bar")));
} }
// Wildcarded host matching is case-insensitive. // Wildcarded host matching is case-insensitive.
{ {
CSPSource source(csp.Get(), "", "FoO.BaR", 0, "", CSPSource::kHasWildcard, CSPSource source(csp.Get(), "", "FoO.BaR", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kHasWildcard, CSPSource::kNoWildcard);
EXPECT_TRUE(source.Matches(KURL(base, "http://sub.foo.bar"))); EXPECT_TRUE(source.Matches(KURL(base, "http://sub.foo.bar")));
EXPECT_FALSE(source.Matches(KURL(base, "http://foo.bar"))); EXPECT_FALSE(source.Matches(KURL(base, "http://foo.bar")));
} }
...@@ -326,12 +329,16 @@ TEST_F(CSPSourceTest, DoesNotSubsume) { ...@@ -326,12 +329,16 @@ TEST_F(CSPSourceTest, DoesNotSubsume) {
const Source a; const Source a;
const Source b; const Source b;
} cases[] = { } cases[] = {
{{"http", "example.com", "/", 0}, {"http", "another.com", "/", 0}}, {{"http", "example.com", "/", CSPSource::kPortUnspecified},
{{"wss", "example.com", "/", 0}, {"http", "example.com", "/", 0}}, {"http", "another.com", "/", CSPSource::kPortUnspecified}},
{{"wss", "example.com", "/", 0}, {"about", "example.com", "/", 0}}, {{"wss", "example.com", "/", CSPSource::kPortUnspecified},
{{"http", "example.com", "/", 0}, {"about", "example.com", "/", 0}}, {"http", "example.com", "/", CSPSource::kPortUnspecified}},
{{"http", "example.com", "/1.html", 0}, {{"wss", "example.com", "/", CSPSource::kPortUnspecified},
{"http", "example.com", "/2.html", 0}}, {"about", "example.com", "/", CSPSource::kPortUnspecified}},
{{"http", "example.com", "/", CSPSource::kPortUnspecified},
{"about", "example.com", "/", CSPSource::kPortUnspecified}},
{{"http", "example.com", "/1.html", CSPSource::kPortUnspecified},
{"http", "example.com", "/2.html", CSPSource::kPortUnspecified}},
{{"http", "example.com", "/", 443}, {"about", "example.com", "/", 800}}, {{"http", "example.com", "/", 443}, {"about", "example.com", "/", 800}},
}; };
for (const auto& test : cases) { for (const auto& test : cases) {
...@@ -362,32 +369,80 @@ TEST_F(CSPSourceTest, Subsumes) { ...@@ -362,32 +369,80 @@ TEST_F(CSPSourceTest, Subsumes) {
bool expected_when_swapped; bool expected_when_swapped;
} cases[] = { } cases[] = {
// Equal signals // Equal signals
{{"http", "/", 0}, {"http", "/", 0}, true, true}, {{"http", "/", CSPSource::kPortUnspecified},
{{"https", "/", 0}, {"https", "/", 0}, true, true}, {"http", "/", CSPSource::kPortUnspecified},
{{"https", "/page1.html", 0}, {"https", "/page1.html", 0}, true, true}, true,
true},
{{"https", "/", CSPSource::kPortUnspecified},
{"https", "/", CSPSource::kPortUnspecified},
true,
true},
{{"https", "/page1.html", CSPSource::kPortUnspecified},
{"https", "/page1.html", CSPSource::kPortUnspecified},
true,
true},
{{"http", "/", 70}, {"http", "/", 70}, true, true}, {{"http", "/", 70}, {"http", "/", 70}, true, true},
{{"https", "/", 70}, {"https", "/", 70}, true, true}, {{"https", "/", 70}, {"https", "/", 70}, true, true},
{{"https", "/page1.html", 0}, {"https", "/page1.html", 0}, true, true}, {{"https", "/page1.html", CSPSource::kPortUnspecified},
{"https", "/page1.html", CSPSource::kPortUnspecified},
true,
true},
{{"http", "/page1.html", 70}, {"http", "/page1.html", 70}, true, true}, {{"http", "/page1.html", 70}, {"http", "/page1.html", 70}, true, true},
{{"https", "/page1.html", 70}, {"https", "/page1.html", 70}, true, true}, {{"https", "/page1.html", 70}, {"https", "/page1.html", 70}, true, true},
{{"http", "/", 0}, {"http", "", 0}, true, true}, {{"http", "/", CSPSource::kPortUnspecified},
{"http", "", CSPSource::kPortUnspecified},
true,
true},
{{"http", "/", 80}, {"http", "", 80}, true, true}, {{"http", "/", 80}, {"http", "", 80}, true, true},
{{"http", "/", 80}, {"https", "", 443}, false, true}, {{"http", "/", 80}, {"https", "", 443}, false, true},
// One stronger signal in the first CSPSource // One stronger signal in the first CSPSource
{{"https", "/", 0}, {"http", "/", 0}, true, false}, {{"https", "/", CSPSource::kPortUnspecified},
{{"http", "/page1.html", 0}, {"http", "/", 0}, true, false}, {"http", "/", CSPSource::kPortUnspecified},
{{"http", "/", 80}, {"http", "/", 0}, true, true}, true,
{{"http", "/", 700}, {"http", "/", 0}, false, false}, false},
{{"http", "/page1.html", CSPSource::kPortUnspecified},
{"http", "/", CSPSource::kPortUnspecified},
true,
false},
{{"http", "/", 80},
{"http", "/", CSPSource::kPortUnspecified},
true,
true},
{{"http", "/", 700},
{"http", "/", CSPSource::kPortUnspecified},
false,
false},
// Two stronger signals in the first CSPSource // Two stronger signals in the first CSPSource
{{"https", "/page1.html", 0}, {"http", "/", 0}, true, false}, {{"https", "/page1.html", CSPSource::kPortUnspecified},
{{"https", "/", 80}, {"http", "/", 0}, false, false}, {"http", "/", CSPSource::kPortUnspecified},
{{"http", "/page1.html", 80}, {"http", "/", 0}, true, false}, true,
false},
{{"https", "/", 80},
{"http", "/", CSPSource::kPortUnspecified},
false,
false},
{{"http", "/page1.html", 80},
{"http", "/", CSPSource::kPortUnspecified},
true,
false},
// Three stronger signals in the first CSPSource // Three stronger signals in the first CSPSource
{{"https", "/page1.html", 70}, {"http", "/", 0}, false, false}, {{"https", "/page1.html", 70},
{"http", "/", CSPSource::kPortUnspecified},
false,
false},
// Mixed signals // Mixed signals
{{"https", "/", 0}, {"http", "/page1.html", 0}, false, false}, {{"https", "/", CSPSource::kPortUnspecified},
{{"https", "/", 0}, {"http", "/", 70}, false, false}, {"http", "/page1.html", CSPSource::kPortUnspecified},
{{"http", "/page1.html", 0}, {"http", "/", 70}, false, false}, false,
false},
{{"https", "/", CSPSource::kPortUnspecified},
{"http", "/", 70},
false,
false},
{{"http", "/page1.html", CSPSource::kPortUnspecified},
{"http", "/", 70},
false,
false},
}; };
for (const auto& test : cases) { for (const auto& test : cases) {
...@@ -490,18 +545,18 @@ TEST_F(CSPSourceTest, WildcardsSubsumes) { ...@@ -490,18 +545,18 @@ TEST_F(CSPSourceTest, WildcardsSubsumes) {
// has a more specific path. // has a more specific path.
for (const auto& test : cases) { for (const auto& test : cases) {
CSPSource* returned = MakeGarbageCollected<CSPSource>( CSPSource* returned = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "example.com", 0, "/", test.a.host_dispotion, csp.Get(), "http", "example.com", CSPSource::kPortUnspecified, "/",
test.a.port_dispotion); test.a.host_dispotion, test.a.port_dispotion);
CSPSource* required = MakeGarbageCollected<CSPSource>( CSPSource* required = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "example.com", 0, "/", test.b.host_dispotion, csp.Get(), "http", "example.com", CSPSource::kPortUnspecified, "/",
test.b.port_dispotion); test.b.host_dispotion, test.b.port_dispotion);
EXPECT_EQ(required->Subsumes(returned), test.expected); EXPECT_EQ(required->Subsumes(returned), test.expected);
// Wildcards should not matter when required csp is stricter than returned // Wildcards should not matter when required csp is stricter than returned
// csp. // csp.
CSPSource* required2 = MakeGarbageCollected<CSPSource>( CSPSource* required2 = MakeGarbageCollected<CSPSource>(
csp.Get(), "https", "example.com", 0, "/", test.b.host_dispotion, csp.Get(), "https", "example.com", CSPSource::kPortUnspecified, "/",
test.b.port_dispotion); test.b.host_dispotion, test.b.port_dispotion);
EXPECT_FALSE(required2->Subsumes(returned)); EXPECT_FALSE(required2->Subsumes(returned));
} }
} }
...@@ -530,11 +585,11 @@ TEST_F(CSPSourceTest, SchemesOnlySubsumes) { ...@@ -530,11 +585,11 @@ TEST_F(CSPSourceTest, SchemesOnlySubsumes) {
for (const auto& test : cases) { for (const auto& test : cases) {
CSPSource* returned = MakeGarbageCollected<CSPSource>( CSPSource* returned = MakeGarbageCollected<CSPSource>(
csp.Get(), test.a_scheme, "example.com", 0, "/", CSPSource::kNoWildcard, csp.Get(), test.a_scheme, "example.com", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard); "/", CSPSource::kNoWildcard, CSPSource::kNoWildcard);
CSPSource* required = MakeGarbageCollected<CSPSource>( CSPSource* required = MakeGarbageCollected<CSPSource>(
csp.Get(), test.b_scheme, "example.com", 0, "/", CSPSource::kNoWildcard, csp.Get(), test.b_scheme, "example.com", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard); "/", CSPSource::kNoWildcard, CSPSource::kNoWildcard);
EXPECT_EQ(required->Subsumes(returned), test.expected); EXPECT_EQ(required->Subsumes(returned), test.expected);
} }
} }
...@@ -552,21 +607,29 @@ TEST_F(CSPSourceTest, IsSimilar) { ...@@ -552,21 +607,29 @@ TEST_F(CSPSourceTest, IsSimilar) {
bool is_similar; bool is_similar;
} cases[] = { } cases[] = {
// Similar // Similar
{{"http", "example.com", "/", 0}, {"http", "example.com", "/", 0}, true}, {{"http", "example.com", "/", CSPSource::kPortUnspecified},
{"http", "example.com", "/", CSPSource::kPortUnspecified},
true},
// Schemes // Schemes
{{"https", "example.com", "/", 0}, {{"https", "example.com", "/", CSPSource::kPortUnspecified},
{"https", "example.com", "/", 0}, {"https", "example.com", "/", CSPSource::kPortUnspecified},
true},
{{"https", "example.com", "/", CSPSource::kPortUnspecified},
{"http", "example.com", "/", CSPSource::kPortUnspecified},
true},
{{"ws", "example.com", "/", CSPSource::kPortUnspecified},
{"wss", "example.com", "/", CSPSource::kPortUnspecified},
true}, true},
{{"https", "example.com", "/", 0}, {"http", "example.com", "/", 0}, true},
{{"ws", "example.com", "/", 0}, {"wss", "example.com", "/", 0}, true},
// Ports // Ports
{{"http", "example.com", "/", 90}, {{"http", "example.com", "/", 90},
{"http", "example.com", "/", 90}, {"http", "example.com", "/", 90},
true}, true},
{{"wss", "example.com", "/", 0}, {{"wss", "example.com", "/", CSPSource::kPortUnspecified},
{"wss", "example.com", "/", 0}, {"wss", "example.com", "/", CSPSource::kPortUnspecified},
true}, // use default port true}, // use default port
{{"http", "example.com", "/", 80}, {"http", "example.com", "/", 0}, true}, {{"http", "example.com", "/", 80},
{"http", "example.com", "/", CSPSource::kPortUnspecified},
true},
{{"http", "example.com", "/", 80}, {{"http", "example.com", "/", 80},
{"https", "example.com", "/", 443}, {"https", "example.com", "/", 443},
true}, true},
...@@ -574,30 +637,34 @@ TEST_F(CSPSourceTest, IsSimilar) { ...@@ -574,30 +637,34 @@ TEST_F(CSPSourceTest, IsSimilar) {
{"https", "example.com", "/", 444}, {"https", "example.com", "/", 444},
false}, false},
// Paths // Paths
{{"http", "example.com", "/", 0}, {{"http", "example.com", "/", CSPSource::kPortUnspecified},
{"http", "example.com", "/1.html", 0}, {"http", "example.com", "/1.html", CSPSource::kPortUnspecified},
true}, true},
{{"http", "example.com", "/", 0}, {"http", "example.com", "", 0}, true}, {{"http", "example.com", "/", CSPSource::kPortUnspecified},
{{"http", "example.com", "/", 0}, {"http", "example.com", "", CSPSource::kPortUnspecified},
{"http", "example.com", "/a/b/", 0},
true}, true},
{{"http", "example.com", "/a/", 0}, {{"http", "example.com", "/", CSPSource::kPortUnspecified},
{"http", "example.com", "/a/", 0}, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified},
true}, true},
{{"http", "example.com", "/a/", 0}, {{"http", "example.com", "/a/", CSPSource::kPortUnspecified},
{"http", "example.com", "/a/b/", 0}, {"http", "example.com", "/a/", CSPSource::kPortUnspecified},
true}, true},
{{"http", "example.com", "/a/", 0}, {{"http", "example.com", "/a/", CSPSource::kPortUnspecified},
{"http", "example.com", "/a/b/1.html", 0}, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified},
true}, true},
{{"http", "example.com", "/1.html", 0}, {{"http", "example.com", "/a/", CSPSource::kPortUnspecified},
{"http", "example.com", "/1.html", 0}, {"http", "example.com", "/a/b/1.html", CSPSource::kPortUnspecified},
true},
{{"http", "example.com", "/1.html", CSPSource::kPortUnspecified},
{"http", "example.com", "/1.html", CSPSource::kPortUnspecified},
true}, true},
// Mixed // Mixed
{{"http", "example.com", "/1.html", 90}, {{"http", "example.com", "/1.html", 90},
{"http", "example.com", "/", 90}, {"http", "example.com", "/", 90},
true}, true},
{{"https", "example.com", "/", 0}, {"http", "example.com", "/", 0}, true}, {{"https", "example.com", "/", CSPSource::kPortUnspecified},
{"http", "example.com", "/", CSPSource::kPortUnspecified},
true},
{{"http", "example.com", "/a/", 90}, {{"http", "example.com", "/a/", 90},
{"https", "example.com", "", 90}, {"https", "example.com", "", 90},
true}, true},
...@@ -608,23 +675,29 @@ TEST_F(CSPSourceTest, IsSimilar) { ...@@ -608,23 +675,29 @@ TEST_F(CSPSourceTest, IsSimilar) {
{"https", "example.com", "/a/b/", 90}, {"https", "example.com", "/a/b/", 90},
true}, true},
// Not Similar // Not Similar
{{"http", "example.com", "/a/", 0}, {{"http", "example.com", "/a/", CSPSource::kPortUnspecified},
{"https", "example.com", "", 90}, {"https", "example.com", "", 90},
false}, false},
{{"https", "example.com", "/", 0}, {{"https", "example.com", "/", CSPSource::kPortUnspecified},
{"https", "example.com", "/", 90}, {"https", "example.com", "/", 90},
false}, false},
{{"http", "example.com", "/", 0}, {"http", "another.com", "/", 0}, false}, {{"http", "example.com", "/", CSPSource::kPortUnspecified},
{{"wss", "example.com", "/", 0}, {"http", "example.com", "/", 0}, false}, {"http", "another.com", "/", CSPSource::kPortUnspecified},
{{"wss", "example.com", "/", 0}, {"about", "example.com", "/", 0}, false}, false},
{{"http", "example.com", "/", 0}, {{"wss", "example.com", "/", CSPSource::kPortUnspecified},
{"about", "example.com", "/", 0}, {"http", "example.com", "/", CSPSource::kPortUnspecified},
false},
{{"wss", "example.com", "/", CSPSource::kPortUnspecified},
{"about", "example.com", "/", CSPSource::kPortUnspecified},
false},
{{"http", "example.com", "/", CSPSource::kPortUnspecified},
{"about", "example.com", "/", CSPSource::kPortUnspecified},
false}, false},
{{"http", "example.com", "/1.html", 0}, {{"http", "example.com", "/1.html", CSPSource::kPortUnspecified},
{"http", "example.com", "/2.html", 0}, {"http", "example.com", "/2.html", CSPSource::kPortUnspecified},
false}, false},
{{"http", "example.com", "/a/1.html", 0}, {{"http", "example.com", "/a/1.html", CSPSource::kPortUnspecified},
{"http", "example.com", "/a/b/", 0}, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified},
false}, false},
{{"http", "example.com", "/", 443}, {{"http", "example.com", "/", 443},
{"about", "example.com", "/", 800}, {"about", "example.com", "/", 800},
...@@ -659,39 +732,55 @@ TEST_F(CSPSourceTest, FirstSubsumesSecond) { ...@@ -659,39 +732,55 @@ TEST_F(CSPSourceTest, FirstSubsumesSecond) {
bool expected; bool expected;
} cases[] = { } cases[] = {
// Subsumed. // Subsumed.
{{"http", "example.com", 0, "/"}, "http", true}, {{"http", "example.com", CSPSource::kPortUnspecified, "/"}, "http", true},
{{"http", "example.com", 0, "/page.html"}, "http", true}, {{"http", "example.com", CSPSource::kPortUnspecified, "/page.html"},
"http",
true},
{{"http", "second-example.com", 80, "/"}, "http", true}, {{"http", "second-example.com", 80, "/"}, "http", true},
{{"https", "second-example.com", 0, "/"}, "http", true}, {{"https", "second-example.com", CSPSource::kPortUnspecified, "/"},
{{"http", "second-example.com", 0, "/page.html"}, "http", true}, "http",
true},
{{"http", "second-example.com", CSPSource::kPortUnspecified,
"/page.html"},
"http",
true},
{{"https", "second-example.com", 80, "/page.html"}, "http", true}, {{"https", "second-example.com", 80, "/page.html"}, "http", true},
{{"https", "second-example.com", 0, "/"}, "https", true}, {{"https", "second-example.com", CSPSource::kPortUnspecified, "/"},
{{"https", "second-example.com", 0, "/page.html"}, "https", true}, "https",
true},
{{"https", "second-example.com", CSPSource::kPortUnspecified,
"/page.html"},
"https",
true},
{{"http", "example.com", 900, "/"}, "http", true}, {{"http", "example.com", 900, "/"}, "http", true},
// NOT subsumed. // NOT subsumed.
{{"http", "second-example.com", 0, "/"}, "wss", false}, {{"http", "second-example.com", CSPSource::kPortUnspecified, "/"},
"wss",
false},
{{"http", "non-example.com", 900, "/"}, "http", false}, {{"http", "non-example.com", 900, "/"}, "http", false},
{{"http", "second-example.com", 0, "/"}, "https", false}, {{"http", "second-example.com", CSPSource::kPortUnspecified, "/"},
"https",
false},
}; };
CSPSource* no_wildcards = MakeGarbageCollected<CSPSource>( CSPSource* no_wildcards = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "example.com", 0, "/", CSPSource::kNoWildcard, csp.Get(), "http", "example.com", CSPSource::kPortUnspecified, "/",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
CSPSource* host_wildcard = MakeGarbageCollected<CSPSource>( CSPSource* host_wildcard = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "third-example.com", 0, "/", CSPSource::kHasWildcard, csp.Get(), "http", "third-example.com", CSPSource::kPortUnspecified, "/",
CSPSource::kNoWildcard); CSPSource::kHasWildcard, CSPSource::kNoWildcard);
CSPSource* port_wildcard = MakeGarbageCollected<CSPSource>( CSPSource* port_wildcard = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "third-example.com", 0, "/", CSPSource::kNoWildcard, csp.Get(), "http", "third-example.com", CSPSource::kPortUnspecified, "/",
CSPSource::kHasWildcard); CSPSource::kNoWildcard, CSPSource::kHasWildcard);
CSPSource* both_wildcards = MakeGarbageCollected<CSPSource>( CSPSource* both_wildcards = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "third-example.com", 0, "/", CSPSource::kHasWildcard, csp.Get(), "http", "third-example.com", CSPSource::kPortUnspecified, "/",
CSPSource::kHasWildcard); CSPSource::kHasWildcard, CSPSource::kHasWildcard);
CSPSource* http_only = MakeGarbageCollected<CSPSource>( CSPSource* http_only = MakeGarbageCollected<CSPSource>(
csp.Get(), "http", "", 0, "", CSPSource::kNoWildcard, csp.Get(), "http", "", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
CSPSource* https_only = MakeGarbageCollected<CSPSource>( CSPSource* https_only = MakeGarbageCollected<CSPSource>(
csp.Get(), "https", "", 0, "", CSPSource::kNoWildcard, csp.Get(), "https", "", CSPSource::kPortUnspecified, "",
CSPSource::kNoWildcard); CSPSource::kNoWildcard, CSPSource::kNoWildcard);
for (const auto& test : cases) { for (const auto& test : cases) {
// Setup default vectors. // Setup default vectors.
...@@ -704,11 +793,13 @@ TEST_F(CSPSourceTest, FirstSubsumesSecond) { ...@@ -704,11 +793,13 @@ TEST_F(CSPSourceTest, FirstSubsumesSecond) {
list_a.push_back(no_wildcards); list_a.push_back(no_wildcards);
// Add CSPSources based on the current test. // Add CSPSources based on the current test.
list_b.push_back(MakeGarbageCollected<CSPSource>( list_b.push_back(MakeGarbageCollected<CSPSource>(
csp.Get(), test.source_b.scheme, test.source_b.host, 0, csp.Get(), test.source_b.scheme, test.source_b.host,
test.source_b.path, CSPSource::kNoWildcard, CSPSource::kNoWildcard)); CSPSource::kPortUnspecified, test.source_b.path, CSPSource::kNoWildcard,
CSPSource::kNoWildcard));
list_a.push_back(MakeGarbageCollected<CSPSource>( list_a.push_back(MakeGarbageCollected<CSPSource>(
csp.Get(), test.scheme_a, "second-example.com", 0, "/", csp.Get(), test.scheme_a, "second-example.com",
CSPSource::kNoWildcard, CSPSource::kNoWildcard)); CSPSource::kPortUnspecified, "/", CSPSource::kNoWildcard,
CSPSource::kNoWildcard));
// listB contains: ["http://example.com/", test.listB] // listB contains: ["http://example.com/", test.listB]
// listA contains: ["http://example.com/", // listA contains: ["http://example.com/",
// test.schemeA + "://second-example.com/"] // test.schemeA + "://second-example.com/"]
...@@ -748,42 +839,42 @@ TEST_F(CSPSourceTest, Intersect) { ...@@ -748,42 +839,42 @@ TEST_F(CSPSourceTest, Intersect) {
const Source b; const Source b;
const Source normalized; const Source normalized;
} cases[] = { } cases[] = {
{{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"ws", "example.com", "/", 0, CSPSource::kNoWildcard, {{"ws", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"wss", "example.com", "/", 0, CSPSource::kNoWildcard, {"wss", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"wss", "example.com", "/", 0, CSPSource::kNoWildcard, {"wss", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
// Wildcards // Wildcards
{{"http", "example.com", "/", 0, CSPSource::kHasWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kHasWildcard, CSPSource::kNoWildcard},
{"http", "sub.example.com", "/", 0, CSPSource::kNoWildcard, {"http", "sub.example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "sub.example.com", "/", 0, CSPSource::kNoWildcard, {"http", "sub.example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "example.com", "/", 0, CSPSource::kHasWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kHasWildcard}, CSPSource::kHasWildcard, CSPSource::kHasWildcard},
{"http", "sub.example.com", "/", 0, CSPSource::kNoWildcard, {"http", "sub.example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "sub.example.com", "/", 0, CSPSource::kNoWildcard, {"http", "sub.example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "example.com", "/", 0, CSPSource::kHasWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kHasWildcard, CSPSource::kNoWildcard},
{"http", "sub.example.com", "/", 0, CSPSource::kNoWildcard, {"http", "sub.example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kHasWildcard}, CSPSource::kNoWildcard, CSPSource::kHasWildcard},
{"http", "sub.example.com", "/", 0, CSPSource::kNoWildcard, {"http", "sub.example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
// Ports // Ports
{{"http", "example.com", "/", 80, CSPSource::kNoWildcard, {{"http", "example.com", "/", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", 80, CSPSource::kNoWildcard, {"http", "example.com", "/", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
{{"http", "example.com", "/", 80, CSPSource::kNoWildcard, {{"http", "example.com", "/", 80, CSPSource::kNoWildcard,
...@@ -799,39 +890,39 @@ TEST_F(CSPSourceTest, Intersect) { ...@@ -799,39 +890,39 @@ TEST_F(CSPSourceTest, Intersect) {
{"https", "example.com", "/", 443, CSPSource::kNoWildcard, {"https", "example.com", "/", 443, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
// Paths // Paths
{{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/1.html", 0, CSPSource::kNoWildcard, {"http", "example.com", "/1.html", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/1.html", 0, CSPSource::kNoWildcard, {"http", "example.com", "/1.html", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "", 0, CSPSource::kNoWildcard, {"http", "example.com", "", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/a/b/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/a/b/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "example.com", "/a/", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/a/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/a/b/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/a/b/", 0, CSPSource::kNoWildcard, {"http", "example.com", "/a/b/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "example.com", "/a/", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/a/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/a/b/1.html", 0, CSPSource::kNoWildcard, {"http", "example.com", "/a/b/1.html", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/a/b/1.html", 0, CSPSource::kNoWildcard, {"http", "example.com", "/a/b/1.html", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
// Mixed // Mixed
{{"http", "example.com", "/1.html", 0, CSPSource::kNoWildcard, {{"http", "example.com", "/1.html", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", 80, CSPSource::kNoWildcard, {"http", "example.com", "/", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"http", "example.com", "/1.html", 80, CSPSource::kNoWildcard, {"http", "example.com", "/1.html", 80, CSPSource::kNoWildcard,
...@@ -851,7 +942,15 @@ TEST_F(CSPSourceTest, Intersect) { ...@@ -851,7 +942,15 @@ TEST_F(CSPSourceTest, Intersect) {
normalized->scheme_, normalized->host_, normalized->scheme_, normalized->host_,
normalized->path_, normalized->port_, normalized->path_, normalized->port_,
normalized->host_wildcard_, normalized->port_wildcard_}; normalized->host_wildcard_, normalized->port_wildcard_};
EXPECT_TRUE(EqualSources(intersect_ab, test.normalized)); EXPECT_TRUE(EqualSources(intersect_ab, test.normalized))
<<
"intersect_ab=" << normalized->scheme_ << normalized->host_
<< normalized->path_ << normalized->port_ << normalized->host_wildcard_
<< normalized->port_wildcard_
<< ", test.normalized=" << test.normalized.scheme
<< test.normalized.host << test.normalized.path << test.normalized.port
<< test.normalized.host_wildcard << test.normalized.port_wildcard;
// Verify the same test with A and B swapped. The result should be // Verify the same test with A and B swapped. The result should be
// identical. // identical.
...@@ -860,7 +959,15 @@ TEST_F(CSPSourceTest, Intersect) { ...@@ -860,7 +959,15 @@ TEST_F(CSPSourceTest, Intersect) {
normalized->scheme_, normalized->host_, normalized->scheme_, normalized->host_,
normalized->path_, normalized->port_, normalized->path_, normalized->port_,
normalized->host_wildcard_, normalized->port_wildcard_}; normalized->host_wildcard_, normalized->port_wildcard_};
EXPECT_TRUE(EqualSources(intersect_ba, test.normalized)); EXPECT_TRUE(EqualSources(intersect_ba, test.normalized))
<<
"intersect_ba=" << normalized->scheme_ << normalized->host_
<< normalized->path_ << normalized->port_ << normalized->host_wildcard_
<< normalized->port_wildcard_
<< ", test.normalized=" << test.normalized.scheme
<< test.normalized.host << test.normalized.path << test.normalized.port
<< test.normalized.host_wildcard << test.normalized.port_wildcard;
} }
} }
...@@ -871,43 +978,58 @@ TEST_F(CSPSourceTest, IntersectSchemesOnly) { ...@@ -871,43 +978,58 @@ TEST_F(CSPSourceTest, IntersectSchemesOnly) {
const Source normalized; const Source normalized;
} cases[] = { } cases[] = {
// Both sources are schemes only. // Both sources are schemes only.
{{"http", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {{"http", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
{"http", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"http", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}}, {"http", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
{{"http", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"https", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {"http", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
{"https", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
{{"ws", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {{"http", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
{"wss", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"wss", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
// One source is a scheme only and the other one has no wildcards.
{{"http", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", 0, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"http", "example.com", "/", 0, CSPSource::kNoWildcard, {"https", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"https", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}},
{{"ws", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"wss", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"wss", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
{{"http", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, // One source is a scheme only and the other one has no wildcards.
{{"http", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard, CSPSource::kNoWildcard},
{"http", "example.com", "/", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard, CSPSource::kNoWildcard}},
{{"http", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"https", "example.com", "/", 80, CSPSource::kNoWildcard, {"https", "example.com", "/", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"https", "example.com", "/", 80, CSPSource::kNoWildcard, {"https", "example.com", "/", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
{{"https", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {{"https", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"http", "example.com", "/page.html", 80, CSPSource::kNoWildcard, {"http", "example.com", "/page.html", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"https", "example.com", "/page.html", 80, CSPSource::kNoWildcard, {"https", "example.com", "/page.html", 80, CSPSource::kNoWildcard,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
// One source is a scheme only and the other has one or two wildcards. // One source is a scheme only and the other has one or two wildcards.
{{"https", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {{"https", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"http", "example.com", "/page.html", 80, CSPSource::kHasWildcard, {"http", "example.com", "/page.html", 80, CSPSource::kHasWildcard,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
{"https", "example.com", "/page.html", 80, CSPSource::kHasWildcard, {"https", "example.com", "/page.html", 80, CSPSource::kHasWildcard,
CSPSource::kNoWildcard}}, CSPSource::kNoWildcard}},
{{"https", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {{"https", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"http", "example.com", "/page.html", 80, CSPSource::kNoWildcard, {"http", "example.com", "/page.html", 80, CSPSource::kNoWildcard,
CSPSource::kHasWildcard}, CSPSource::kHasWildcard},
{"https", "example.com", "/page.html", 80, CSPSource::kNoWildcard, {"https", "example.com", "/page.html", 80, CSPSource::kNoWildcard,
CSPSource::kHasWildcard}}, CSPSource::kHasWildcard}},
{{"https", "", "", 0, CSPSource::kNoWildcard, CSPSource::kNoWildcard}, {{"https", "", "", CSPSource::kPortUnspecified, CSPSource::kNoWildcard,
CSPSource::kNoWildcard},
{"http", "example.com", "/page.html", 80, CSPSource::kHasWildcard, {"http", "example.com", "/page.html", 80, CSPSource::kHasWildcard,
CSPSource::kHasWildcard}, CSPSource::kHasWildcard},
{"https", "example.com", "/page.html", 80, CSPSource::kHasWildcard, {"https", "example.com", "/page.html", 80, CSPSource::kHasWildcard,
...@@ -1002,8 +1124,8 @@ TEST_F(CSPSourceTest, MatchingAsSelf) { ...@@ -1002,8 +1124,8 @@ TEST_F(CSPSourceTest, MatchingAsSelf) {
"wss://example.com:443/", "wss://example.com:443/",
true}, true},
// Ports not set (aka default) // Ports not set (aka default)
{{"https", "example.com", "", 0, CSPSource::kNoWildcard, {{"https", "example.com", "", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
"wss://example.com:443/", "wss://example.com:443/",
true}, true},
{{"https", "example.com", "", 443, CSPSource::kNoWildcard, {{"https", "example.com", "", 443, CSPSource::kNoWildcard,
...@@ -1042,8 +1164,8 @@ TEST_F(CSPSourceTest, MatchingAsSelf) { ...@@ -1042,8 +1164,8 @@ TEST_F(CSPSourceTest, MatchingAsSelf) {
CSPSource::kNoWildcard}, CSPSource::kNoWildcard},
"custom-scheme://example.com/some-path", "custom-scheme://example.com/some-path",
false}, false},
{{"http", "example.com", "", 0, CSPSource::kNoWildcard, {{"http", "example.com", "", CSPSource::kPortUnspecified,
CSPSource::kNoWildcard}, CSPSource::kNoWildcard, CSPSource::kNoWildcard},
"custom-scheme://example.com/some-path", "custom-scheme://example.com/some-path",
false}, false},
}; };
......
...@@ -161,7 +161,7 @@ void SourceListDirective::Parse(const UChar* begin, const UChar* end) { ...@@ -161,7 +161,7 @@ void SourceListDirective::Parse(const UChar* begin, const UChar* end) {
SkipWhile<UChar, IsSourceCharacter>(position, end); SkipWhile<UChar, IsSourceCharacter>(position, end);
String scheme, host, path; String scheme, host, path;
int port = 0; int port = CSPSource::kPortUnspecified;
CSPSource::WildcardDisposition host_wildcard = CSPSource::kNoWildcard; CSPSource::WildcardDisposition host_wildcard = CSPSource::kNoWildcard;
CSPSource::WildcardDisposition port_wildcard = CSPSource::kNoWildcard; CSPSource::WildcardDisposition port_wildcard = CSPSource::kNoWildcard;
...@@ -339,7 +339,7 @@ bool SourceListDirective::ParseSource( ...@@ -339,7 +339,7 @@ bool SourceListDirective::ParseSource(
if (!ParsePort(begin_port, begin_path, port, port_wildcard)) if (!ParsePort(begin_port, begin_path, port, port_wildcard))
return false; return false;
} else { } else {
*port = 0; *port = CSPSource::kPortUnspecified;
} }
if (begin_path != end) { if (begin_path != end) {
...@@ -559,7 +559,7 @@ bool SourceListDirective::ParsePort( ...@@ -559,7 +559,7 @@ bool SourceListDirective::ParsePort(
int* port, int* port,
CSPSource::WildcardDisposition* port_wildcard) { CSPSource::WildcardDisposition* port_wildcard) {
DCHECK(begin <= end); DCHECK(begin <= end);
DCHECK_EQ(*port, 0); DCHECK_EQ(*port, CSPSource::kPortUnspecified);
DCHECK(*port_wildcard == CSPSource::kNoWildcard); DCHECK(*port_wildcard == CSPSource::kNoWildcard);
if (!SkipExactly<UChar>(begin, end, ':')) if (!SkipExactly<UChar>(begin, end, ':'))
...@@ -569,7 +569,7 @@ bool SourceListDirective::ParsePort( ...@@ -569,7 +569,7 @@ bool SourceListDirective::ParsePort(
return false; return false;
if (end - begin == 1 && *begin == '*') { if (end - begin == 1 && *begin == '*') {
*port = 0; *port = CSPSource::kPortUnspecified;
*port_wildcard = CSPSource::kHasWildcard; *port_wildcard = CSPSource::kHasWildcard;
return true; return true;
} }
...@@ -672,18 +672,18 @@ HeapVector<Member<CSPSource>> SourceListDirective::GetSources( ...@@ -672,18 +672,18 @@ HeapVector<Member<CSPSource>> SourceListDirective::GetSources(
HeapVector<Member<CSPSource>> sources = list_; HeapVector<Member<CSPSource>> sources = list_;
if (allow_star_) { if (allow_star_) {
sources.push_back(MakeGarbageCollected<CSPSource>( sources.push_back(MakeGarbageCollected<CSPSource>(
policy_, "ftp", String(), 0, String(), CSPSource::kNoWildcard, policy_, "ftp", String(), CSPSource::kPortUnspecified, String(),
CSPSource::kNoWildcard)); CSPSource::kNoWildcard, CSPSource::kNoWildcard));
sources.push_back(MakeGarbageCollected<CSPSource>( sources.push_back(MakeGarbageCollected<CSPSource>(
policy_, "ws", String(), 0, String(), CSPSource::kNoWildcard, policy_, "ws", String(), CSPSource::kPortUnspecified, String(),
CSPSource::kNoWildcard)); CSPSource::kNoWildcard, CSPSource::kNoWildcard));
sources.push_back(MakeGarbageCollected<CSPSource>( sources.push_back(MakeGarbageCollected<CSPSource>(
policy_, "http", String(), 0, String(), CSPSource::kNoWildcard, policy_, "http", String(), CSPSource::kPortUnspecified, String(),
CSPSource::kNoWildcard)); CSPSource::kNoWildcard, CSPSource::kNoWildcard));
if (self) { if (self) {
sources.push_back(MakeGarbageCollected<CSPSource>( sources.push_back(MakeGarbageCollected<CSPSource>(
policy_, self->GetScheme(), String(), 0, String(), policy_, self->GetScheme(), String(), CSPSource::kPortUnspecified,
CSPSource::kNoWildcard, CSPSource::kNoWildcard)); String(), CSPSource::kNoWildcard, CSPSource::kNoWildcard));
} }
} else if (allow_self_ && self) { } else if (allow_self_ && self) {
sources.push_back(self); sources.push_back(self);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment