| Index: third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp
 | 
| diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp b/third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp
 | 
| index 05d42a15802e9f8243719c10f19dc191b7f48a59..606be966cd99e491a89d75f4febed36261c0a870 100644
 | 
| --- a/third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp
 | 
| +++ b/third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp
 | 
| @@ -123,4 +123,331 @@ TEST_F(CSPSourceTest, InsecureHostSchemePortMatchesSecurePort) {
 | 
|    EXPECT_FALSE(source.matches(KURL(base, "https://not-example.com:443/")));
 | 
|  }
 | 
|  
 | 
| +TEST_F(CSPSourceTest, IsSimilar) {
 | 
| +  struct Source {
 | 
| +    const char* scheme;
 | 
| +    const char* host;
 | 
| +    const char* path;
 | 
| +    const int port;
 | 
| +  };
 | 
| +  struct TestCase {
 | 
| +    const Source a;
 | 
| +    const Source b;
 | 
| +    bool isSimilar;
 | 
| +  } cases[] = {
 | 
| +      // Similar
 | 
| +      {{"http", "example.com", "/", 0}, {"http", "example.com", "/", 0}, true},
 | 
| +      // Schemes
 | 
| +      {{"https", "example.com", "/", 0},
 | 
| +       {"https", "example.com", "/", 0},
 | 
| +       true},
 | 
| +      {{"https", "example.com", "/", 0}, {"http", "example.com", "/", 0}, true},
 | 
| +      {{"ws", "example.com", "/", 0}, {"wss", "example.com", "/", 0}, true},
 | 
| +      // Ports
 | 
| +      {{"http", "example.com", "/", 90},
 | 
| +       {"http", "example.com", "/", 90},
 | 
| +       true},
 | 
| +      {{"wss", "example.com", "/", 0},
 | 
| +       {"wss", "example.com", "/", 0},
 | 
| +       true},  // use default port
 | 
| +      {{"http", "example.com", "/", 80}, {"http", "example.com", "/", 0}, true},
 | 
| +      // Paths
 | 
| +      {{"http", "example.com", "/", 0},
 | 
| +       {"http", "example.com", "/1.html", 0},
 | 
| +       true},
 | 
| +      {{"http", "example.com", "/", 0}, {"http", "example.com", "", 0}, true},
 | 
| +      {{"http", "example.com", "/", 0},
 | 
| +       {"http", "example.com", "/a/b/", 0},
 | 
| +       true},
 | 
| +      {{"http", "example.com", "/a/", 0},
 | 
| +       {"http", "example.com", "/a/", 0},
 | 
| +       true},
 | 
| +      {{"http", "example.com", "/a/", 0},
 | 
| +       {"http", "example.com", "/a/b/", 0},
 | 
| +       true},
 | 
| +      {{"http", "example.com", "/a/", 0},
 | 
| +       {"http", "example.com", "/a/b/1.html", 0},
 | 
| +       true},
 | 
| +      {{"http", "example.com", "/1.html", 0},
 | 
| +       {"http", "example.com", "/1.html", 0},
 | 
| +       true},
 | 
| +      // Mixed
 | 
| +      {{"http", "example.com", "/1.html", 90},
 | 
| +       {"http", "example.com", "/", 90},
 | 
| +       true},
 | 
| +      {{"https", "example.com", "/", 0}, {"http", "example.com", "/", 0}, true},
 | 
| +      {{"http", "example.com", "/a/", 90},
 | 
| +       {"https", "example.com", "", 90},
 | 
| +       true},
 | 
| +      {{"wss", "example.com", "/a/", 90},
 | 
| +       {"ws", "example.com", "/a/b/", 90},
 | 
| +       true},
 | 
| +      {{"https", "example.com", "/a/", 90},
 | 
| +       {"https", "example.com", "/a/b/", 90},
 | 
| +       true},
 | 
| +      // Not Similar
 | 
| +      {{"http", "example.com", "/a/", 0},
 | 
| +       {"https", "example.com", "", 90},
 | 
| +       false},
 | 
| +      {{"https", "example.com", "/", 0},
 | 
| +       {"https", "example.com", "/", 90},
 | 
| +       false},
 | 
| +      {{"http", "example.com", "/", 0}, {"http", "another.com", "/", 0}, false},
 | 
| +      {{"wss", "example.com", "/", 0}, {"http", "example.com", "/", 0}, false},
 | 
| +      {{"wss", "example.com", "/", 0}, {"about", "example.com", "/", 0}, false},
 | 
| +      {{"http", "example.com", "/", 0},
 | 
| +       {"about", "example.com", "/", 0},
 | 
| +       false},
 | 
| +      {{"http", "example.com", "/1.html", 0},
 | 
| +       {"http", "example.com", "/2.html", 0},
 | 
| +       false},
 | 
| +      {{"http", "example.com", "/a/1.html", 0},
 | 
| +       {"http", "example.com", "/a/b/", 0},
 | 
| +       false},
 | 
| +      {{"http", "example.com", "/", 443},
 | 
| +       {"about", "example.com", "/", 800},
 | 
| +       false},
 | 
| +  };
 | 
| +
 | 
| +  for (const auto& test : cases) {
 | 
| +    CSPSource* returned = new CSPSource(
 | 
| +        csp.get(), test.a.scheme, test.a.host, test.a.port, test.a.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    CSPSource* required = new CSPSource(
 | 
| +        csp.get(), test.b.scheme, test.b.host, test.b.port, test.b.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    EXPECT_EQ(returned->isSimilar(required), test.isSimilar);
 | 
| +    // Verify the same test with a and b swapped.
 | 
| +    EXPECT_EQ(required->isSimilar(returned), test.isSimilar);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +TEST_F(CSPSourceTest, IsSubsumedByNotSimilar) {
 | 
| +  struct Source {
 | 
| +    const char* scheme;
 | 
| +    const char* host;
 | 
| +    const char* path;
 | 
| +    const int port;
 | 
| +  };
 | 
| +  struct TestCase {
 | 
| +    const Source a;
 | 
| +    const Source b;
 | 
| +  } cases[] = {
 | 
| +      {{"http", "example.com", "/", 0}, {"http", "another.com", "/", 0}},
 | 
| +      {{"wss", "example.com", "/", 0}, {"http", "example.com", "/", 0}},
 | 
| +      {{"wss", "example.com", "/", 0}, {"about", "example.com", "/", 0}},
 | 
| +      {{"http", "example.com", "/", 0}, {"about", "example.com", "/", 0}},
 | 
| +      {{"http", "example.com", "/1.html", 0},
 | 
| +       {"http", "example.com", "/2.html", 0}},
 | 
| +      {{"http", "example.com", "/", 443}, {"about", "example.com", "/", 800}},
 | 
| +  };
 | 
| +  for (const auto& test : cases) {
 | 
| +    CSPSource* returned = new CSPSource(
 | 
| +        csp.get(), test.a.scheme, test.a.host, test.a.port, test.a.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    CSPSource* required = new CSPSource(
 | 
| +        csp.get(), test.b.scheme, test.b.host, test.b.port, test.b.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    EXPECT_FALSE(returned->isSubsumedBy(required));
 | 
| +    // Verify the same test with a and b swapped.
 | 
| +    EXPECT_FALSE(required->isSubsumedBy(returned));
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +TEST_F(CSPSourceTest, IsSubsumed) {
 | 
| +  struct Source {
 | 
| +    const char* scheme;
 | 
| +    const char* path;
 | 
| +    const int port;
 | 
| +  };
 | 
| +  struct TestCase {
 | 
| +    const Source a;
 | 
| +    const Source b;
 | 
| +    bool expected;
 | 
| +    bool expectedWhenSwapped;
 | 
| +  } cases[] = {
 | 
| +      // Equal signals
 | 
| +      {{"http", "/", 0}, {"http", "/", 0}, true, true},
 | 
| +      {{"https", "/", 0}, {"https", "/", 0}, true, true},
 | 
| +      {{"https", "/page1.html", 0}, {"https", "/page1.html", 0}, true, true},
 | 
| +      {{"http", "/", 80}, {"http", "/", 80}, true, true},
 | 
| +      {{"https", "/", 80}, {"https", "/", 80}, true, true},
 | 
| +      {{"https", "/page1.html", 0}, {"https", "/page1.html", 0}, true, true},
 | 
| +      {{"http", "/page1.html", 80}, {"http", "/page1.html", 80}, true, true},
 | 
| +      {{"https", "/page1.html", 80}, {"https", "/page1.html", 80}, true, true},
 | 
| +      // One stronger signal in the first CSPSource
 | 
| +      {{"https", "/", 0}, {"http", "/", 0}, true, false},
 | 
| +      {{"http", "/page1.html", 0}, {"http", "/", 0}, true, false},
 | 
| +      {{"http", "/", 80},
 | 
| +       {"http", "/", 0},
 | 
| +       true,
 | 
| +       false},  // 80 does match to default port
 | 
| +      {{"http", "/", 800},
 | 
| +       {"http", "/", 0},
 | 
| +       false,
 | 
| +       false},  // 800 does not match to default port
 | 
| +      // Two stronger signals in the first CSPSource
 | 
| +      {{"https", "/page1.html", 0}, {"http", "/", 0}, true, false},
 | 
| +      {{"https", "/", 80}, {"http", "/", 0}, true, false},
 | 
| +      {{"http", "/page1.html", 80}, {"http", "/", 0}, true, false},
 | 
| +      // Three stronger signals in the first CSPSource
 | 
| +      {{"https", "/page1.html", 80}, {"http", "/", 0}, true, false},
 | 
| +      // Mixed signals
 | 
| +      {{"https", "/", 0}, {"http", "/page1.html", 0}, false, false},
 | 
| +      {{"https", "/", 0}, {"http", "/", 80}, false, false},
 | 
| +      {{"http", "/page1.html", 0}, {"http", "/", 80}, false, false},
 | 
| +  };
 | 
| +
 | 
| +  for (const auto& test : cases) {
 | 
| +    CSPSource* returned = new CSPSource(
 | 
| +        csp.get(), test.a.scheme, "example.com", test.a.port, test.a.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    CSPSource* required = new CSPSource(
 | 
| +        csp.get(), test.b.scheme, "example.com", test.b.port, test.b.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    EXPECT_EQ(returned->isSubsumedBy(required), test.expected);
 | 
| +    // Verify the same test with a and b swapped.
 | 
| +    EXPECT_EQ(required->isSubsumedBy(returned), test.expectedWhenSwapped);
 | 
| +  }
 | 
| +
 | 
| +  // When returned CSP has a wildcard but the required csp doesn't, then it is
 | 
| +  // not subsumed.
 | 
| +  for (const auto& test : cases) {
 | 
| +    CSPSource* returned = new CSPSource(
 | 
| +        csp.get(), test.a.scheme, "example.com", test.a.port, test.a.path,
 | 
| +        CSPSource::HasWildcard, CSPSource::NoWildcard);
 | 
| +    CSPSource* required = new CSPSource(
 | 
| +        csp.get(), test.b.scheme, "example.com", test.b.port, test.b.path,
 | 
| +        CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +
 | 
| +    EXPECT_FALSE(returned->isSubsumedBy(required));
 | 
| +
 | 
| +    // If required csp also allows a wildcard in host, then the answer should be
 | 
| +    // as expected.
 | 
| +    CSPSource* required2 = new CSPSource(
 | 
| +        csp.get(), test.b.scheme, "example.com", test.b.port, test.b.path,
 | 
| +        CSPSource::HasWildcard, CSPSource::NoWildcard);
 | 
| +    EXPECT_EQ(returned->isSubsumedBy(required2), test.expected);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +TEST_F(CSPSourceTest, IsSubsumedByWildcards) {
 | 
| +  struct Wildcards {
 | 
| +    CSPSource::WildcardDisposition hostDispotion;
 | 
| +    CSPSource::WildcardDisposition portDispotion;
 | 
| +  };
 | 
| +  struct TestCase {
 | 
| +    const Wildcards a;
 | 
| +    const Wildcards b;
 | 
| +    bool expected;
 | 
| +  } cases[] = {
 | 
| +      // One out of four possible wildcards.
 | 
| +      {{CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::NoWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::NoWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       true},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       true},
 | 
| +      // Two out of four possible wildcards.
 | 
| +      {{CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::NoWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       true},
 | 
| +      {{CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       true},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       true},
 | 
| +      // Three out of four possible wildcards.
 | 
| +      {{CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       false},
 | 
| +      {{CSPSource::HasWildcard, CSPSource::NoWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       true},
 | 
| +      {{CSPSource::NoWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       true},
 | 
| +      // Four out of four possible wildcards.
 | 
| +      {{CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       {CSPSource::HasWildcard, CSPSource::HasWildcard},
 | 
| +       true},
 | 
| +  };
 | 
| +
 | 
| +  // There are different cases for wildcards but now also the second CSPSource
 | 
| +  // has a more specific path.
 | 
| +  for (const auto& test : cases) {
 | 
| +    CSPSource* returned =
 | 
| +        new CSPSource(csp.get(), "http", "example.com", 0, "/",
 | 
| +                      test.a.hostDispotion, test.a.portDispotion);
 | 
| +    CSPSource* required =
 | 
| +        new CSPSource(csp.get(), "http", "example.com", 0, "/",
 | 
| +                      test.b.hostDispotion, test.b.portDispotion);
 | 
| +    EXPECT_EQ(returned->isSubsumedBy(required), test.expected);
 | 
| +
 | 
| +    // Wildcards should not matter when required csp is stricter than returned
 | 
| +    // csp.
 | 
| +    CSPSource* required2 =
 | 
| +        new CSPSource(csp.get(), "https", "example.com", 0, "/",
 | 
| +                      test.b.hostDispotion, test.b.portDispotion);
 | 
| +    EXPECT_FALSE(returned->isSubsumedBy(required2));
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +TEST_F(CSPSourceTest, IsSubsumedBySchemesOnly) {
 | 
| +  struct TestCase {
 | 
| +    String aScheme;
 | 
| +    String bScheme;
 | 
| +    bool expected;
 | 
| +  } cases[] = {
 | 
| +      // HTTP
 | 
| +      {"http", "http", true},
 | 
| +      {"http", "https", false},
 | 
| +      {"https", "http", true},
 | 
| +      {"https", "https", true},
 | 
| +      // WSS
 | 
| +      {"ws", "ws", true},
 | 
| +      {"ws", "wss", false},
 | 
| +      {"wss", "ws", true},
 | 
| +      {"wss", "wss", true},
 | 
| +      // Unequal
 | 
| +      {"ws", "http", false},
 | 
| +      {"http", "ws", false},
 | 
| +      {"http", "about", false},
 | 
| +  };
 | 
| +  for (const auto& test : cases) {
 | 
| +    CSPSource* returned =
 | 
| +        new CSPSource(csp.get(), test.aScheme, "example.com", 0, "/",
 | 
| +                      CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +    CSPSource* required =
 | 
| +        new CSPSource(csp.get(), test.bScheme, "example.com", 0, "/",
 | 
| +                      CSPSource::NoWildcard, CSPSource::NoWildcard);
 | 
| +    EXPECT_EQ(returned->isSubsumedBy(required), test.expected);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  }  // namespace blink
 | 
| 
 |