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 |