15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/appcache/appcache_manifest_parser.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "url/gurl.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheManifestParserTest : public testing::Test { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(AppCacheManifestParserTest, NoData) { 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url; 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AppCacheManifest manifest; 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_FALSE(ParseManifest(url, "", 0, 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(ParseManifest(url, "CACHE MANIFEST\r", 0, // Len is 0. 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST(AppCacheManifestParserTest, CheckSignature) { 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GURL url; 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AppCacheManifest manifest; 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::string kBadSignatures[] = { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "foo", 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST;V2\r", // not followed by whitespace 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST#bad\r", // no whitespace before comment 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cache manifest ", // wrong case 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#CACHE MANIFEST\r", // comment 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xCACHE MANIFEST\n", // bad first char 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " CACHE MANIFEST\r", // begins with whitespace 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\xEF\xBE\xBF" "CACHE MANIFEST\r", // bad UTF-8 BOM value 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kBadSignatures); ++i) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string bad = kBadSignatures[i]; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(ParseManifest(url, bad.c_str(), bad.length(), 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string kGoodSignatures[] = { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST", 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "CACHE MANIFEST ", 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "CACHE MANIFEST\r", 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST\n", 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST\r\n", 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST\t# ignore me\r", 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE MANIFEST ignore\r\n", 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CHROMIUM CACHE MANIFEST\r\n", 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\xEF\xBB\xBF" "CACHE MANIFEST \r\n", // BOM present 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kGoodSignatures); ++i) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string good = kGoodSignatures[i]; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ParseManifest(url, good.c_str(), good.length(), 618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST(AppCacheManifestParserTest, NoManifestUrl) { 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AppCacheManifest manifest; 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string kData("CACHE MANIFEST\r" 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "relative/tobase.com\r" 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "http://absolute.com/addme.com"); 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const GURL kUrl; 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.explicit_urls.empty()); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.fallback_namespaces.empty()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manifest.online_whitelist_all); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(AppCacheManifestParserTest, ExplicitUrls) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheManifest manifest; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL kUrl("http://www.foo.com"); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kData("CACHE MANIFEST\r" 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "relative/one\r" 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "# some comment\r" 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://www.foo.com/two#strip\r\n" 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NETWORK:\r" 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \t CACHE:\r" 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "HTTP://www.diff.com/three\r" 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FALLBACK:\r" 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \t # another comment with leading whitespace\n" 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "IGNORE:\r" 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://www.foo.com/ignore\r" 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "CACHE: \r" 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "garbage:#!@\r" 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "https://www.foo.com/diffscheme \t \r" 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \t relative/four#stripme\n\r" 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "*\r"); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.fallback_namespaces.empty()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manifest.online_whitelist_all); 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_set<std::string> urls = manifest.explicit_urls; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const size_t kExpected = 5; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(kExpected, urls.size()); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/relative/one") != urls.end()); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/two") != urls.end()); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.diff.com/three") != urls.end()); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/relative/four") != urls.end()); 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Wildcard is treated as a relative URL in explicit section. 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/*") != urls.end()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should get the same results with intercepts disallowed. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest = AppCacheManifest(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PARSE_MANIFEST_PER_STANDARD, manifest)); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.fallback_namespaces.empty()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manifest.online_whitelist_all); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) urls = manifest.explicit_urls; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(kExpected, urls.size()); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/relative/one") != urls.end()); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/two") != urls.end()); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.diff.com/three") != urls.end()); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/relative/four") != urls.end()); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Wildcard is treated as a relative URL in explicit section. 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(urls.find("http://www.foo.com/*") != urls.end()); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(AppCacheManifestParserTest, WhitelistUrls) { 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AppCacheManifest manifest; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL kUrl("http://www.bar.com"); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kData("CACHE MANIFEST\r" 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NETWORK:\r" 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "relative/one\r" 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "# a comment\r" 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://www.bar.com/two\r" 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "HTTP://www.diff.com/three#strip\n\r" 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FALLBACK:\r" 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "garbage\r" 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "UNKNOWN:\r" 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "http://www.bar.com/ignore\r" 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE:\r" 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NETWORK:\r" 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "https://www.wrongscheme.com\n" 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "relative/four#stripref \t \r" 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://www.five.com\r\n" 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "*foo\r"); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(manifest.explicit_urls.empty()); 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_TRUE(manifest.fallback_namespaces.empty()); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manifest.intercept_namespaces.empty()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manifest.online_whitelist_all); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AppCacheNamespaceVector& online = manifest.online_whitelist_namespaces; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kExpected = 6; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kExpected, online.size()); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(APPCACHE_NETWORK_NAMESPACE, online[0].type); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(online[0].is_pattern); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(online[0].target_url.is_empty()); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(GURL("http://www.bar.com/relative/one"), online[0].namespace_url); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(GURL("http://www.bar.com/two"), online[1].namespace_url); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(GURL("http://www.diff.com/three"), online[2].namespace_url); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(GURL("http://www.bar.com/relative/four"), online[3].namespace_url); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(GURL("http://www.five.com"), online[4].namespace_url); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(GURL("http://www.bar.com/*foo"), online[5].namespace_url); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(AppCacheManifestParserTest, FallbackUrls) { 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AppCacheManifest manifest; 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL kUrl("http://glorp.com"); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kData("CACHE MANIFEST\r" 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "# a comment\r" 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CACHE:\r" 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NETWORK:\r" 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UNKNOWN:\r" 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FALLBACK:\r" 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "relative/one \t \t http://glorp.com/onefb \t \r" 186 "*\r" 187 "https://glorp.com/wrong http://glorp.com/wrongfb\r" 188 "http://glorp.com/two#strip relative/twofb\r" 189 "HTTP://glorp.com/three relative/threefb#strip\n" 190 "http://glorp.com/three http://glorp.com/three-dup\r" 191 "http://glorp.com/solo \t \r\n" 192 "http://diff.com/ignore http://glorp.com/wronghost\r" 193 "http://glorp.com/wronghost http://diff.com/ohwell\r" 194 "relative/badscheme ftp://glorp.com/ignored\r" 195 "garbage\r\n" 196 "CACHE:\r" 197 "# only fallback urls in this test\r" 198 "FALLBACK:\n" 199 "relative/four#strip relative/fourfb#strip\r" 200 "http://www.glorp.com/notsame relative/skipped\r"); 201 202 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 203 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 204 EXPECT_TRUE(manifest.explicit_urls.empty()); 205 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 206 EXPECT_FALSE(manifest.online_whitelist_all); 207 208 const AppCacheNamespaceVector& fallbacks = manifest.fallback_namespaces; 209 const size_t kExpected = 5; 210 ASSERT_EQ(kExpected, fallbacks.size()); 211 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[0].type); 212 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[1].type); 213 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[2].type); 214 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[3].type); 215 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[4].type); 216 EXPECT_EQ(GURL("http://glorp.com/relative/one"), 217 fallbacks[0].namespace_url); 218 EXPECT_EQ(GURL("http://glorp.com/onefb"), 219 fallbacks[0].target_url); 220 EXPECT_EQ(GURL("http://glorp.com/two"), 221 fallbacks[1].namespace_url); 222 EXPECT_EQ(GURL("http://glorp.com/relative/twofb"), 223 fallbacks[1].target_url); 224 EXPECT_EQ(GURL("http://glorp.com/three"), 225 fallbacks[2].namespace_url); 226 EXPECT_EQ(GURL("http://glorp.com/relative/threefb"), 227 fallbacks[2].target_url); 228 EXPECT_EQ(GURL("http://glorp.com/three"), // duplicates are stored 229 fallbacks[3].namespace_url); 230 EXPECT_EQ(GURL("http://glorp.com/three-dup"), 231 fallbacks[3].target_url); 232 EXPECT_EQ(GURL("http://glorp.com/relative/four"), 233 fallbacks[4].namespace_url); 234 EXPECT_EQ(GURL("http://glorp.com/relative/fourfb"), 235 fallbacks[4].target_url); 236 237 EXPECT_TRUE(manifest.intercept_namespaces.empty()); 238} 239 240TEST(AppCacheManifestParserTest, FallbackUrlsWithPort) { 241 AppCacheManifest manifest; 242 const GURL kUrl("http://www.portme.com:1234"); 243 const std::string kData("CACHE MANIFEST\r" 244 "FALLBACK:\r" 245 "http://www.portme.com:1234/one relative/onefb\r" 246 "HTTP://www.portme.com:9876/wrong http://www.portme.com:1234/ignore\r" 247 "http://www.portme.com:1234/stillwrong http://www.portme.com:42/boo\r" 248 "relative/two relative/twofb\r" 249 "http://www.portme.com:1234/three HTTP://www.portme.com:1234/threefb\r" 250 "http://www.portme.com/noport http://www.portme.com:1234/skipped\r" 251 "http://www.portme.com:1234/skipme http://www.portme.com/noport\r"); 252 253 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 254 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 255 EXPECT_TRUE(manifest.explicit_urls.empty()); 256 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 257 EXPECT_FALSE(manifest.online_whitelist_all); 258 259 const AppCacheNamespaceVector& fallbacks = manifest.fallback_namespaces; 260 const size_t kExpected = 3; 261 ASSERT_EQ(kExpected, fallbacks.size()); 262 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[0].type); 263 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[1].type); 264 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[2].type); 265 EXPECT_EQ(GURL("http://www.portme.com:1234/one"), 266 fallbacks[0].namespace_url); 267 EXPECT_EQ(GURL("http://www.portme.com:1234/relative/onefb"), 268 fallbacks[0].target_url); 269 EXPECT_EQ(GURL("http://www.portme.com:1234/relative/two"), 270 fallbacks[1].namespace_url); 271 EXPECT_EQ(GURL("http://www.portme.com:1234/relative/twofb"), 272 fallbacks[1].target_url); 273 EXPECT_EQ(GURL("http://www.portme.com:1234/three"), 274 fallbacks[2].namespace_url); 275 EXPECT_EQ(GURL("http://www.portme.com:1234/threefb"), 276 fallbacks[2].target_url); 277 278 EXPECT_TRUE(manifest.intercept_namespaces.empty()); 279} 280 281TEST(AppCacheManifestParserTest, InterceptUrls) { 282 AppCacheManifest manifest; 283 const GURL kUrl("http://www.portme.com:1234"); 284 const std::string kData("CHROMIUM CACHE MANIFEST\r" 285 "CHROMIUM-INTERCEPT:\r" 286 "http://www.portme.com:1234/one return relative/int1\r" 287 "HTTP://www.portme.com:9/wrong return http://www.portme.com:1234/ignore\r" 288 "http://www.portme.com:1234/wrong return http://www.portme.com:9/boo\r" 289 "relative/two return relative/int2\r" 290 "relative/three wrong relative/threefb\r" 291 "http://www.portme.com:1234/three return HTTP://www.portme.com:1234/int3\r" 292 "http://www.portme.com/noport return http://www.portme.com:1234/skipped\r" 293 "http://www.portme.com:1234/skipme return http://www.portme.com/noport\r" 294 "relative/wrong/again missing/intercept_type\r"); 295 296 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 297 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 298 EXPECT_TRUE(manifest.fallback_namespaces.empty()); 299 EXPECT_TRUE(manifest.explicit_urls.empty()); 300 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 301 EXPECT_FALSE(manifest.online_whitelist_all); 302 303 const AppCacheNamespaceVector& intercepts = manifest.intercept_namespaces; 304 const size_t kExpected = 3; 305 ASSERT_EQ(kExpected, intercepts.size()); 306 EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, intercepts[0].type); 307 EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, intercepts[1].type); 308 EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, intercepts[2].type); 309 EXPECT_EQ(GURL("http://www.portme.com:1234/one"), 310 intercepts[0].namespace_url); 311 EXPECT_EQ(GURL("http://www.portme.com:1234/relative/int1"), 312 intercepts[0].target_url); 313 EXPECT_EQ(GURL("http://www.portme.com:1234/relative/two"), 314 intercepts[1].namespace_url); 315 EXPECT_EQ(GURL("http://www.portme.com:1234/relative/int2"), 316 intercepts[1].target_url); 317 EXPECT_EQ(GURL("http://www.portme.com:1234/three"), 318 intercepts[2].namespace_url); 319 EXPECT_EQ(GURL("http://www.portme.com:1234/int3"), 320 intercepts[2].target_url); 321 322 // Disallow intercepts ths time. 323 manifest = AppCacheManifest(); 324 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 325 PARSE_MANIFEST_PER_STANDARD, manifest)); 326 EXPECT_TRUE(manifest.fallback_namespaces.empty()); 327 EXPECT_TRUE(manifest.explicit_urls.empty()); 328 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 329 EXPECT_TRUE(manifest.intercept_namespaces.empty()); 330 EXPECT_FALSE(manifest.online_whitelist_all); 331} 332 333TEST(AppCacheManifestParserTest, ComboUrls) { 334 AppCacheManifest manifest; 335 const GURL kUrl("http://combo.com:42"); 336 const std::string kData("CACHE MANIFEST\r" 337 "relative/explicit-1\r" 338 "# some comment\r" 339 "http://combo.com:99/explicit-2#strip\r" 340 "NETWORK:\r" 341 "http://combo.com/whitelist-1\r" 342 "HTTP://www.diff.com/whitelist-2#strip\r" 343 "*\r" 344 "CACHE:\n\r" 345 "http://www.diff.com/explicit-3\r" 346 "FALLBACK:\r" 347 "http://combo.com:42/fallback-1 http://combo.com:42/fallback-1b\r" 348 "relative/fallback-2 relative/fallback-2b\r" 349 "UNKNOWN:\r\n" 350 "http://combo.com/ignoreme\r" 351 "relative/still-ignored\r" 352 "NETWORK:\r\n" 353 "relative/whitelist-3#strip\r" 354 "http://combo.com:99/whitelist-4\r"); 355 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 356 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 357 EXPECT_TRUE(manifest.online_whitelist_all); 358 359 base::hash_set<std::string> urls = manifest.explicit_urls; 360 size_t expected = 3; 361 ASSERT_EQ(expected, urls.size()); 362 EXPECT_TRUE(urls.find("http://combo.com:42/relative/explicit-1") != 363 urls.end()); 364 EXPECT_TRUE(urls.find("http://combo.com:99/explicit-2") != urls.end()); 365 EXPECT_TRUE(urls.find("http://www.diff.com/explicit-3") != urls.end()); 366 367 const AppCacheNamespaceVector& online = manifest.online_whitelist_namespaces; 368 expected = 4; 369 ASSERT_EQ(expected, online.size()); 370 EXPECT_EQ(GURL("http://combo.com/whitelist-1"), 371 online[0].namespace_url); 372 EXPECT_EQ(GURL("http://www.diff.com/whitelist-2"), 373 online[1].namespace_url); 374 EXPECT_EQ(GURL("http://combo.com:42/relative/whitelist-3"), 375 online[2].namespace_url); 376 EXPECT_EQ(GURL("http://combo.com:99/whitelist-4"), 377 online[3].namespace_url); 378 379 const AppCacheNamespaceVector& fallbacks = manifest.fallback_namespaces; 380 expected = 2; 381 ASSERT_EQ(expected, fallbacks.size()); 382 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[0].type); 383 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[1].type); 384 EXPECT_EQ(GURL("http://combo.com:42/fallback-1"), 385 fallbacks[0].namespace_url); 386 EXPECT_EQ(GURL("http://combo.com:42/fallback-1b"), 387 fallbacks[0].target_url); 388 EXPECT_EQ(GURL("http://combo.com:42/relative/fallback-2"), 389 fallbacks[1].namespace_url); 390 EXPECT_EQ(GURL("http://combo.com:42/relative/fallback-2b"), 391 fallbacks[1].target_url); 392 393 EXPECT_TRUE(manifest.intercept_namespaces.empty()); 394} 395 396TEST(AppCacheManifestParserTest, UnusualUtf8) { 397 AppCacheManifest manifest; 398 const GURL kUrl("http://bad.com"); 399 const std::string kData("CACHE MANIFEST\r" 400 "\xC0" "invalidutf8\r" 401 "nonbmp" "\xF1\x84\xAB\xBC\r"); 402 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 403 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 404 base::hash_set<std::string> urls = manifest.explicit_urls; 405 EXPECT_TRUE(urls.find("http://bad.com/%EF%BF%BDinvalidutf8") != urls.end()); 406 EXPECT_TRUE(urls.find("http://bad.com/nonbmp%F1%84%AB%BC") != urls.end()); 407} 408 409TEST(AppCacheManifestParserTest, IgnoreAfterSpace) { 410 AppCacheManifest manifest; 411 const GURL kUrl("http://smorg.borg"); 412 const std::string kData( 413 "CACHE MANIFEST\r" 414 "resource.txt this stuff after the white space should be ignored\r"); 415 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 416 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 417 418 base::hash_set<std::string> urls = manifest.explicit_urls; 419 EXPECT_TRUE(urls.find("http://smorg.borg/resource.txt") != urls.end()); 420} 421 422TEST(AppCacheManifestParserTest, DifferentOriginUrlWithSecureScheme) { 423 AppCacheManifest manifest; 424 const GURL kUrl("https://www.foo.com"); 425 const std::string kData("CACHE MANIFEST\r" 426 "CACHE: \r" 427 "relative/secureschemesameorigin\r" 428 "https://www.foo.com/secureschemesameorigin\r" 429 "http://www.xyz.com/secureschemedifforigin\r" 430 "https://www.xyz.com/secureschemedifforigin\r"); 431 432 EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(), 433 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 434 EXPECT_TRUE(manifest.fallback_namespaces.empty()); 435 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 436 437 base::hash_set<std::string> urls = manifest.explicit_urls; 438 const size_t kExpected = 3; 439 ASSERT_EQ(kExpected, urls.size()); 440 EXPECT_TRUE(urls.find("https://www.foo.com/relative/secureschemesameorigin") 441 != urls.end()); 442 EXPECT_TRUE(urls.find("https://www.foo.com/secureschemesameorigin") != 443 urls.end()); 444 EXPECT_FALSE(urls.find("http://www.xyz.com/secureschemedifforigin") != 445 urls.end()); 446 EXPECT_TRUE(urls.find("https://www.xyz.com/secureschemedifforigin") != 447 urls.end()); 448} 449 450TEST(AppCacheManifestParserTest, PatternMatching) { 451 const GURL kUrl("http://foo.com/manifest"); 452 const std::string kManifestBody( 453 "CACHE MANIFEST\r" 454 "CACHE: \r" 455 "http://foo.com/page.html\r" 456 "CHROMIUM-INTERCEPT:\r" 457 "http://foo.com/intercept_prefix return /prefix\r" 458 "http://foo.com/intercept_pattern return /pattern isPattern\r" 459 "http://foo.com/*/intercept_pattern?query return /pattern isPattern\r" 460 "FALLBACK:\r" 461 "http://foo.com/fallback_prefix /prefix wrongAnnotation\r" 462 "http://foo.com/fallback_pattern* /pattern\tisPattern \r" 463 "NETWORK:\r" 464 "*\r" 465 "isPattern\r" // should not be interpretted as a pattern 466 "http://foo.com/network_pattern* isPattern\r"); 467 468 469 AppCacheManifest manifest; 470 EXPECT_TRUE(ParseManifest(kUrl, kManifestBody.c_str(), 471 kManifestBody.length(), 472 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest)); 473 EXPECT_TRUE(manifest.online_whitelist_all); 474 EXPECT_EQ(1u, manifest.explicit_urls.size()); 475 EXPECT_EQ(3u, manifest.intercept_namespaces.size()); 476 EXPECT_EQ(2u, manifest.fallback_namespaces.size()); 477 EXPECT_EQ(2u, manifest.online_whitelist_namespaces.size()); 478 EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, 479 manifest.intercept_namespaces[0].type); 480 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, manifest.fallback_namespaces[0].type); 481 EXPECT_EQ(APPCACHE_NETWORK_NAMESPACE, 482 manifest.online_whitelist_namespaces[0].type); 483 EXPECT_FALSE(manifest.intercept_namespaces[0].is_pattern); 484 EXPECT_TRUE(manifest.intercept_namespaces[1].is_pattern); 485 EXPECT_TRUE(manifest.intercept_namespaces[2].is_pattern); 486 EXPECT_FALSE(manifest.fallback_namespaces[0].is_pattern); 487 EXPECT_TRUE(manifest.fallback_namespaces[1].is_pattern); 488 EXPECT_FALSE(manifest.online_whitelist_namespaces[0].is_pattern); 489 EXPECT_TRUE(manifest.online_whitelist_namespaces[1].is_pattern); 490 EXPECT_EQ( 491 GURL("http://foo.com/*/intercept_pattern?query"), 492 manifest.intercept_namespaces[2].namespace_url); 493 EXPECT_EQ( 494 GURL("http://foo.com/pattern"), 495 manifest.intercept_namespaces[2].target_url); 496 EXPECT_EQ( 497 GURL("http://foo.com/fallback_pattern*"), 498 manifest.fallback_namespaces[1].namespace_url); 499 EXPECT_EQ( 500 GURL("http://foo.com/pattern"), 501 manifest.fallback_namespaces[1].target_url); 502 EXPECT_EQ( 503 GURL("http://foo.com/isPattern"), 504 manifest.online_whitelist_namespaces[0].namespace_url); 505 EXPECT_EQ( 506 GURL(), 507 manifest.online_whitelist_namespaces[0].target_url); 508 EXPECT_EQ( 509 GURL("http://foo.com/network_pattern*"), 510 manifest.online_whitelist_namespaces[1].namespace_url); 511 EXPECT_EQ( 512 GURL(), 513 manifest.online_whitelist_namespaces[1].target_url); 514} 515 516} // namespace content 517