Chromium Code Reviews| 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..12ab8eeac7a84a3343871b2ae8a903e5be00ae0b 100644 |
| --- a/third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp |
| +++ b/third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp |
| @@ -13,12 +13,40 @@ |
| namespace blink { |
| +enum NormalizationReturn { |
| + FirstCSPSource, |
| + SecondCSPSource, |
| + NewCSPSource, |
| + NullCSPSource |
| +}; |
| + |
| class CSPSourceTest : public ::testing::Test { |
| public: |
| CSPSourceTest() : csp(ContentSecurityPolicy::create()) {} |
| protected: |
| Persistent<ContentSecurityPolicy> csp; |
| + void assertNormalizationReturn(CSPSource* a, |
| + CSPSource* b, |
| + CSPSource* returned, |
| + NormalizationReturn expected) { |
| + switch (expected) { |
| + case NullCSPSource: |
| + EXPECT_EQ(returned, nullptr); |
| + break; |
| + case FirstCSPSource: |
| + EXPECT_EQ(returned, a); |
| + break; |
| + case SecondCSPSource: |
| + EXPECT_EQ(returned, b); |
| + break; |
| + case NewCSPSource: |
| + EXPECT_NE(returned, a); |
| + EXPECT_NE(returned, b); |
| + EXPECT_NE(returned, nullptr); |
| + break; |
| + } |
| + } |
| }; |
| TEST_F(CSPSourceTest, BasicMatching) { |
| @@ -123,4 +151,397 @@ TEST_F(CSPSourceTest, InsecureHostSchemePortMatchesSecurePort) { |
| EXPECT_FALSE(source.matches(KURL(base, "https://not-example.com:443/"))); |
| } |
| +TEST_F(CSPSourceTest, GetPrefferredCSPMixed) { |
| + struct TestCase { |
| + String aScheme; |
| + String bScheme; |
| + String aPath; |
| + String bPath; |
| + int aPort; |
| + int bPort; |
| + const NormalizationReturn expected; |
|
Mike West
2016/10/26 11:40:29
Here, and elsewhere, would you mind reordering the
|
| + } cases[] = { |
| + // Equal signals |
| + {"http", "http", "/", "/", 0, 0, NullCSPSource}, |
| + // One stronger signal in 'a' |
| + {"https", "http", "/", "/", 0, 0, FirstCSPSource}, |
| + {"http", "http", "/page1.html", "/", 0, 0, FirstCSPSource}, |
| + {"http", "http", "/", "/", 800, 0, FirstCSPSource}, |
| + // Two stronger signals in 'a' |
| + {"https", "http", "/page1.html", "/", 0, 0, FirstCSPSource}, |
| + {"https", "http", "/", "/", 800, 0, FirstCSPSource}, |
| + {"http", "http", "/page1.html", "/", 800, 0, FirstCSPSource}, |
| + // Three stronger signals in 'a' |
| + {"https", "http", "/page1.html", "/", 800, 0, FirstCSPSource}, |
| + // Mixed signals |
| + {"https", "http", "/", "/page1.html", 0, 0, NewCSPSource}, |
| + {"https", "http", "/", "/", 0, 800, NewCSPSource}, |
| + {"http", "http", "/page1.html", "/", 0, 800, NewCSPSource}, |
| + }; |
| + |
| + for (const auto& test : cases) { |
| + CSPSource* a = |
| + new CSPSource(csp.get(), test.aScheme, "example.com", test.aPort, |
| + test.aPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + CSPSource* b = |
| + new CSPSource(csp.get(), test.bScheme, "example.com", test.bPort, |
| + test.bPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + assertNormalizationReturn(a, b, a->getPreferredCSPSource(b), test.expected); |
| + } |
| + |
| + // Verify the same test with a and b swapped. |
| + for (const auto& test : cases) { |
| + CSPSource* b = |
| + new CSPSource(csp.get(), test.aScheme, "example.com", test.aPort, |
| + test.aPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + CSPSource* a = |
| + new CSPSource(csp.get(), test.bScheme, "example.com", test.bPort, |
| + test.bPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + // Reverse the order of comparison for First vs Second but the call to the |
| + // function is the same. |
| + assertNormalizationReturn(b, a, a->getPreferredCSPSource(b), test.expected); |
|
Mike West
2016/10/26 11:40:29
Why do you need a separate loop, rather than addin
|
| + } |
| +} |
| + |
| +TEST_F(CSPSourceTest, NormalizingCSPSourcesProtocols) { |
| + struct TestCase { |
| + String aScheme; |
| + String bScheme; |
| + NormalizationReturn expected; |
| + } cases[] = { |
| + // HTTP |
| + {"http", "http", FirstCSPSource}, |
| + {"http", "https", SecondCSPSource}, |
| + {"https", "http", FirstCSPSource}, |
| + {"https", "https", FirstCSPSource}, |
| + // WSS |
| + {"ws", "ws", FirstCSPSource}, |
| + {"ws", "wss", SecondCSPSource}, |
| + {"wss", "ws", FirstCSPSource}, |
| + {"wss", "wss", FirstCSPSource}, |
| + // Unequal |
| + {"ws", "http", NullCSPSource}, |
| + {"http", "ws", NullCSPSource}, |
| + {"http", "about", NullCSPSource}, |
| + }; |
| + |
| + for (const auto& test : cases) { |
| + CSPSource* a = new CSPSource(csp.get(), test.aScheme, "example.com", 0, "/", |
| + CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + CSPSource* b = new CSPSource(csp.get(), test.bScheme, "example.com", 0, "/", |
| + CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), test.expected); |
|
Mike West
2016/10/26 11:40:29
Might as well do the inverse here as well.
|
| + } |
| +} |
| + |
| +TEST_F(CSPSourceTest, NormalizingCSPSourcesSchemesWithWildcards) { |
| + struct TestCase { |
| + String aScheme; |
| + String bScheme; |
| + bool aHasHost; |
| + bool bHasHost; |
| + NormalizationReturn expected; |
| + } cases[] = { |
| + // "http", "http" |
| + {"http", "http", true, true, FirstCSPSource}, |
| + {"http", "http", false, true, SecondCSPSource}, |
| + {"http", "http", true, false, FirstCSPSource}, |
| + {"http", "http", false, false, FirstCSPSource}, |
| + // "https", "http" |
| + {"https", "http", true, true, FirstCSPSource}, |
| + {"https", "http", false, true, NewCSPSource}, |
| + {"https", "http", true, false, FirstCSPSource}, |
| + {"https", "http", false, false, FirstCSPSource}, |
| + // "http", "https" |
| + {"http", "https", true, true, SecondCSPSource}, |
| + {"http", "https", false, true, SecondCSPSource}, |
| + {"http", "https", true, false, NewCSPSource}, |
| + {"http", "https", false, false, SecondCSPSource}, |
| + // "https", "https" |
| + {"https", "https", true, true, FirstCSPSource}, |
| + {"https", "https", false, true, SecondCSPSource}, |
| + {"https", "https", true, false, FirstCSPSource}, |
| + {"https", "https", false, false, FirstCSPSource}, |
| + // Unequal |
| + {"ws", "http", true, true, NullCSPSource}, |
| + {"http", "ws", true, true, NullCSPSource}, |
| + {"http", "about", true, true, NullCSPSource}, |
| + {"ws", "http", false, true, NullCSPSource}, |
| + {"http", "ws", false, true, NullCSPSource}, |
| + {"http", "about", false, true, NullCSPSource}, |
| + {"ws", "http", true, false, NullCSPSource}, |
| + {"http", "ws", true, false, NullCSPSource}, |
| + {"http", "about", true, false, NullCSPSource}, |
| + {"ws", "http", false, false, NullCSPSource}, |
| + {"http", "ws", false, false, NullCSPSource}, |
| + {"http", "about", false, false, NullCSPSource}, |
| + }; |
| + |
| + for (const auto& test : cases) { |
| + String aHost = test.aHasHost ? "example.com" : ""; |
| + String bHost = test.bHasHost ? "example.com" : ""; |
| + |
| + CSPSource* a = new CSPSource(csp.get(), test.aScheme, aHost, 0, "/", |
| + CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + CSPSource* b = new CSPSource(csp.get(), test.bScheme, bHost, 0, "/", |
| + CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), test.expected); |
| + } |
| +} |
| + |
| +TEST_F(CSPSourceTest, NormalizingCSPSourcesNotSimilar) { |
| + struct TestCase { |
| + String aScheme; |
| + String bScheme; |
| + String aHost; |
| + String bHost; |
| + String aPath; |
| + String bPath; |
| + int aPort; |
| + int bPort; |
| + NormalizationReturn expected; |
| + } cases[] = { |
| + {"http", "http", "example.com", "another.com", "/", "/", 0, 0}, |
| + {"wss", "http", "example.com", "example.com", "/", "/", 0, 0}, |
| + {"wss", "about", "example.com", "example.com", "/", "/", 0, 0}, |
| + {"http", "about", "example.com", "example.com", "/", "/", 0, 0}, |
| + {"http", "http", "example.com", "example.com", "/path1.html", |
| + "/path2.html", 0, 0}, |
| + {"http", "http", "example.com", "example.com", "/", "/", 433, 800}, |
| + }; |
| + |
| + for (const auto& test : cases) { |
| + CSPSource* a = |
| + new CSPSource(csp.get(), test.aScheme, test.aHost, test.aPort, |
| + test.aPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + CSPSource* b = |
| + new CSPSource(csp.get(), test.bScheme, test.bHost, test.bPort, |
| + test.bPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), NullCSPSource); |
| + } |
| + |
| + // Verify the same test with a and b swapped. |
| + for (const auto& test : cases) { |
| + CSPSource* b = |
| + new CSPSource(csp.get(), test.aScheme, test.aHost, test.aPort, |
| + test.aPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + CSPSource* a = |
| + new CSPSource(csp.get(), test.bScheme, test.bHost, test.bPort, |
| + test.bPath, CSPSource::NoWildcard, CSPSource::NoWildcard); |
| + |
| + // Reverse the order of comparison for First vs Second but the call to the |
| + // function is the same. |
| + assertNormalizationReturn(b, a, a->getNormalized(b), NullCSPSource); |
| + } |
| +} |
| + |
| +TEST_F(CSPSourceTest, NormalizingCSPSourcesWildcardsInHostsPorts) { |
| + // Hosts must be equal, schemes matching as well as paths. |
| + struct TestCase { |
| + CSPSource::WildcardDisposition aHostDispotion; |
| + CSPSource::WildcardDisposition aPortDispotion; |
| + CSPSource::WildcardDisposition bHostDispotion; |
| + CSPSource::WildcardDisposition bPortDispotion; |
| + NormalizationReturn expected; |
| + } cases[] = { |
| + // One out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::NoWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::NoWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, FirstCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, FirstCSPSource}, |
| + // Two out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, FirstCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, NewCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, NewCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, FirstCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, FirstCSPSource}, |
| + // Three out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, FirstCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, FirstCSPSource}, |
| + // Four out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, FirstCSPSource}, |
| + }; |
| + |
| + for (const auto& test : cases) { |
| + CSPSource* a = new CSPSource(csp.get(), "http", "example.com", 0, "/", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = new CSPSource(csp.get(), "http", "example.com", 0, "/", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), test.expected); |
| + } |
| + |
| + // If hosts are not matching, wildcards should not matter. |
| + for (const auto& test : cases) { |
| + NormalizationReturn expected = NullCSPSource; |
| + CSPSource* a = new CSPSource(csp.get(), "http", "a.com", 0, "/", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = new CSPSource(csp.get(), "http", "b.com", 0, "/", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), expected); |
| + } |
| + |
| + // If schemes are not matching, wildcards should not matter. |
| + for (const auto& test : cases) { |
| + NormalizationReturn expected = NullCSPSource; |
| + CSPSource* a = new CSPSource(csp.get(), "wss", "example.com", 0, "/", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = new CSPSource(csp.get(), "http", "example.com", 0, "/", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), expected); |
| + } |
| + |
| + // If paths are not matching, wildcards should not matter. |
| + for (const auto& test : cases) { |
| + NormalizationReturn expected = NullCSPSource; |
| + CSPSource* a = |
| + new CSPSource(csp.get(), "wss", "example.com", 0, "/path1.html", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = |
| + new CSPSource(csp.get(), "http", "example.com", 0, "/path2.html", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), expected); |
| + } |
| + |
| + // If first CSP source is just a scheme, wildcards should not matter. |
| + for (const auto& test : cases) { |
| + NormalizationReturn expected = SecondCSPSource; |
| + CSPSource* a = new CSPSource(csp.get(), "http", "", 0, "/", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = |
| + new CSPSource(csp.get(), "http", "example.com", 0, "/path2.html", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), expected); |
| + } |
| + |
| + // If there are many different signals, new CSPSource will be created now |
| + // matter what. |
| + // In this case higher scheme in the first and more precise path in the |
| + // second. |
| + for (const auto& test : cases) { |
| + NormalizationReturn expected = NewCSPSource; |
| + CSPSource* a = new CSPSource(csp.get(), "https", "example.com", 0, "/", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = |
| + new CSPSource(csp.get(), "http", "example.com", 0, "/path2.html", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), expected); |
| + } |
| + |
| + // If there are many different signals, new CSPSource will be created now |
| + // matter what. |
| + // In this case higher scheme in the second and more precise path in the |
| + // first. |
| + for (const auto& test : cases) { |
| + NormalizationReturn expected = NewCSPSource; |
| + CSPSource* a = |
| + new CSPSource(csp.get(), "http", "example.com", 0, "/path2.html", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = new CSPSource(csp.get(), "https", "example.com", 0, "/", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), expected); |
| + } |
| +} |
| + |
| +TEST_F(CSPSourceTest, NormalizingCSPSourcesWildcardsInHostsPortsWithPreferred) { |
| + // Hosts must be equal, schemes matching as well as paths. |
| + struct TestCase { |
| + CSPSource::WildcardDisposition aHostDispotion; |
| + CSPSource::WildcardDisposition aPortDispotion; |
| + CSPSource::WildcardDisposition bHostDispotion; |
| + CSPSource::WildcardDisposition bPortDispotion; |
| + NormalizationReturn expected; |
| + } cases[] = { |
| + // One out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::NoWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::NoWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, NewCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, NewCSPSource}, |
| + // Two out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, NewCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, NewCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, SecondCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, NewCSPSource}, |
| + // Three out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::NoWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::NoWildcard, |
| + CSPSource::HasWildcard, SecondCSPSource}, |
| + {CSPSource::HasWildcard, CSPSource::NoWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, NewCSPSource}, |
| + {CSPSource::NoWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, NewCSPSource}, |
| + // Four out of four possible wildcards. |
| + {CSPSource::HasWildcard, CSPSource::HasWildcard, CSPSource::HasWildcard, |
| + CSPSource::HasWildcard, SecondCSPSource}, |
| + }; |
| + |
| + // There are different cases for wildcards but now also the second CSPSource |
| + // has a more specific path. |
| + for (const auto& test : cases) { |
| + CSPSource* a = new CSPSource(csp.get(), "http", "example.com", 0, "/", |
| + test.aHostDispotion, test.aPortDispotion); |
| + |
| + CSPSource* b = |
| + new CSPSource(csp.get(), "http", "example.com", 0, "/page1.html", |
| + test.bHostDispotion, test.bPortDispotion); |
| + |
| + assertNormalizationReturn(a, b, a->getNormalized(b), test.expected); |
| + } |
| +} |
| + |
| } // namespace blink |