url_matcher_unittest.cc 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/url_matcher/url_matcher.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/strings/string_util.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. #include "url/gurl.h"
  11. using base::MatcherStringPattern;
  12. namespace url_matcher {
  13. //
  14. // URLMatcherCondition
  15. //
  16. TEST(URLMatcherConditionTest, Constructors) {
  17. MatcherStringPattern pattern("example.com", 1);
  18. URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern);
  19. EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m1.criterion());
  20. EXPECT_EQ(&pattern, m1.string_pattern());
  21. URLMatcherCondition m2;
  22. m2 = m1;
  23. EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m2.criterion());
  24. EXPECT_EQ(&pattern, m2.string_pattern());
  25. URLMatcherCondition m3(m1);
  26. EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m3.criterion());
  27. EXPECT_EQ(&pattern, m3.string_pattern());
  28. }
  29. TEST(URLMatcherSchemeFilter, TestMatching) {
  30. URLMatcherSchemeFilter filter1("https");
  31. std::vector<std::string> filter2_content;
  32. filter2_content.push_back("http");
  33. filter2_content.push_back("https");
  34. URLMatcherSchemeFilter filter2(filter2_content);
  35. GURL matching_url("https://www.foobar.com");
  36. GURL non_matching_url("http://www.foobar.com");
  37. EXPECT_TRUE(filter1.IsMatch(matching_url));
  38. EXPECT_FALSE(filter1.IsMatch(non_matching_url));
  39. EXPECT_TRUE(filter2.IsMatch(matching_url));
  40. EXPECT_TRUE(filter2.IsMatch(non_matching_url));
  41. }
  42. TEST(URLMatcherPortFilter, TestMatching) {
  43. std::vector<URLMatcherPortFilter::Range> ranges;
  44. ranges.push_back(URLMatcherPortFilter::CreateRange(80, 90));
  45. ranges.push_back(URLMatcherPortFilter::CreateRange(8080));
  46. URLMatcherPortFilter filter(ranges);
  47. EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com")));
  48. EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:80")));
  49. EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:81")));
  50. EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:90")));
  51. EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:8080")));
  52. EXPECT_FALSE(filter.IsMatch(GURL("http://www.example.com:79")));
  53. EXPECT_FALSE(filter.IsMatch(GURL("http://www.example.com:91")));
  54. EXPECT_FALSE(filter.IsMatch(GURL("https://www.example.com")));
  55. }
  56. TEST(URLMatcherConditionTest, IsFullURLCondition) {
  57. MatcherStringPattern pattern("example.com", 1);
  58. EXPECT_FALSE(URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, &pattern)
  59. .IsFullURLCondition());
  60. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::HOST_CONTAINS, &pattern)
  61. .IsFullURLCondition());
  62. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::PATH_CONTAINS, &pattern)
  63. .IsFullURLCondition());
  64. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::QUERY_CONTAINS, &pattern)
  65. .IsFullURLCondition());
  66. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_PREFIX, &pattern)
  67. .IsFullURLCondition());
  68. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_SUFFIX, &pattern)
  69. .IsFullURLCondition());
  70. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_CONTAINS, &pattern)
  71. .IsFullURLCondition());
  72. EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_EQUALS, &pattern)
  73. .IsFullURLCondition());
  74. }
  75. TEST(URLMatcherConditionTest, IsMatch) {
  76. GURL url1("http://www.example.com/www.foobar.com/index.html");
  77. GURL url2("http://www.foobar.com/example.com/index.html");
  78. MatcherStringPattern pattern("example.com", 1);
  79. URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern);
  80. std::set<MatcherStringPattern::ID> matching_patterns;
  81. // matches = {0} --> matcher did not indicate that m1 was a match.
  82. matching_patterns.insert(0);
  83. EXPECT_FALSE(m1.IsMatch(matching_patterns, url1));
  84. // matches = {0, 1} --> matcher did indicate that m1 was a match.
  85. matching_patterns.insert(1);
  86. EXPECT_TRUE(m1.IsMatch(matching_patterns, url1));
  87. // For m2 we use a HOST_CONTAINS test, which requires a post-validation
  88. // whether the match reported by the SubstringSetMatcher occurs really
  89. // in the correct url component.
  90. URLMatcherCondition m2(URLMatcherCondition::HOST_CONTAINS, &pattern);
  91. EXPECT_TRUE(m2.IsMatch(matching_patterns, url1));
  92. EXPECT_FALSE(m2.IsMatch(matching_patterns, url2));
  93. }
  94. TEST(URLMatcherConditionTest, Comparison) {
  95. MatcherStringPattern p1("foobar.com", 1);
  96. MatcherStringPattern p2("foobar.com", 2);
  97. // The first component of each test is expected to be < than the second.
  98. URLMatcherCondition test_smaller[][2] = {
  99. {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
  100. URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, &p1)},
  101. {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
  102. URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p2)},
  103. {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, nullptr),
  104. URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p2)},
  105. {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
  106. URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, nullptr)},
  107. };
  108. for (size_t i = 0; i < std::size(test_smaller); ++i) {
  109. EXPECT_TRUE(test_smaller[i][0] < test_smaller[i][1])
  110. << "Test " << i << " of test_smaller failed";
  111. EXPECT_FALSE(test_smaller[i][1] < test_smaller[i][0])
  112. << "Test " << i << " of test_smaller failed";
  113. }
  114. URLMatcherCondition test_equal[][2] = {
  115. {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
  116. URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1)},
  117. {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, nullptr),
  118. URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, nullptr)},
  119. };
  120. for (size_t i = 0; i < std::size(test_equal); ++i) {
  121. EXPECT_FALSE(test_equal[i][0] < test_equal[i][1])
  122. << "Test " << i << " of test_equal failed";
  123. EXPECT_FALSE(test_equal[i][1] < test_equal[i][0])
  124. << "Test " << i << " of test_equal failed";
  125. }
  126. }
  127. //
  128. // URLMatcherConditionFactory
  129. //
  130. namespace {
  131. bool Matches(const URLMatcherCondition& condition, const std::string& text) {
  132. return text.find(condition.string_pattern()->pattern()) != std::string::npos;
  133. }
  134. } // namespace
  135. TEST(URLMatcherConditionFactoryTest, GURLCharacterSet) {
  136. // GURL guarantees that neither domain, nor path, nor query may contain
  137. // non ASCII-7 characters. We test this here, because a change to this
  138. // guarantee breaks this implementation horribly.
  139. GURL url("http://www.föö.com/föö?föö#föö");
  140. EXPECT_TRUE(base::IsStringASCII(url.host()));
  141. EXPECT_TRUE(base::IsStringASCII(url.path()));
  142. EXPECT_TRUE(base::IsStringASCII(url.query()));
  143. EXPECT_TRUE(base::IsStringASCII(url.ref()));
  144. }
  145. TEST(URLMatcherConditionFactoryTest, Criteria) {
  146. URLMatcherConditionFactory factory;
  147. EXPECT_EQ(URLMatcherCondition::HOST_PREFIX,
  148. factory.CreateHostPrefixCondition("foo").criterion());
  149. EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX,
  150. factory.CreateHostSuffixCondition("foo").criterion());
  151. EXPECT_EQ(URLMatcherCondition::HOST_CONTAINS,
  152. factory.CreateHostContainsCondition("foo").criterion());
  153. EXPECT_EQ(URLMatcherCondition::HOST_EQUALS,
  154. factory.CreateHostEqualsCondition("foo").criterion());
  155. EXPECT_EQ(URLMatcherCondition::PATH_PREFIX,
  156. factory.CreatePathPrefixCondition("foo").criterion());
  157. EXPECT_EQ(URLMatcherCondition::PATH_SUFFIX,
  158. factory.CreatePathSuffixCondition("foo").criterion());
  159. EXPECT_EQ(URLMatcherCondition::PATH_CONTAINS,
  160. factory.CreatePathContainsCondition("foo").criterion());
  161. EXPECT_EQ(URLMatcherCondition::PATH_EQUALS,
  162. factory.CreatePathEqualsCondition("foo").criterion());
  163. EXPECT_EQ(URLMatcherCondition::QUERY_PREFIX,
  164. factory.CreateQueryPrefixCondition("foo").criterion());
  165. EXPECT_EQ(URLMatcherCondition::QUERY_SUFFIX,
  166. factory.CreateQuerySuffixCondition("foo").criterion());
  167. EXPECT_EQ(URLMatcherCondition::QUERY_CONTAINS,
  168. factory.CreateQueryContainsCondition("foo").criterion());
  169. EXPECT_EQ(URLMatcherCondition::QUERY_EQUALS,
  170. factory.CreateQueryEqualsCondition("foo").criterion());
  171. EXPECT_EQ(
  172. URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX,
  173. factory.CreateHostSuffixPathPrefixCondition("foo", "bar").criterion());
  174. EXPECT_EQ(
  175. URLMatcherCondition::HOST_EQUALS_PATH_PREFIX,
  176. factory.CreateHostEqualsPathPrefixCondition("foo", "bar").criterion());
  177. EXPECT_EQ(URLMatcherCondition::URL_PREFIX,
  178. factory.CreateURLPrefixCondition("foo").criterion());
  179. EXPECT_EQ(URLMatcherCondition::URL_SUFFIX,
  180. factory.CreateURLSuffixCondition("foo").criterion());
  181. EXPECT_EQ(URLMatcherCondition::URL_CONTAINS,
  182. factory.CreateURLContainsCondition("foo").criterion());
  183. EXPECT_EQ(URLMatcherCondition::URL_EQUALS,
  184. factory.CreateURLEqualsCondition("foo").criterion());
  185. EXPECT_EQ(URLMatcherCondition::URL_MATCHES,
  186. factory.CreateURLMatchesCondition("foo").criterion());
  187. }
  188. TEST(URLMatcherConditionFactoryTest, TestSingletonProperty) {
  189. URLMatcherConditionFactory factory;
  190. URLMatcherCondition c1 = factory.CreateHostEqualsCondition("www.google.com");
  191. URLMatcherCondition c2 = factory.CreateHostEqualsCondition("www.google.com");
  192. EXPECT_EQ(c1.criterion(), c2.criterion());
  193. EXPECT_EQ(c1.string_pattern(), c2.string_pattern());
  194. URLMatcherCondition c3 = factory.CreateHostEqualsCondition("www.google.de");
  195. EXPECT_EQ(c2.criterion(), c3.criterion());
  196. EXPECT_NE(c2.string_pattern(), c3.string_pattern());
  197. EXPECT_NE(c2.string_pattern()->id(), c3.string_pattern()->id());
  198. EXPECT_NE(c2.string_pattern()->pattern(), c3.string_pattern()->pattern());
  199. URLMatcherCondition c4 = factory.CreateURLMatchesCondition("www.google.com");
  200. URLMatcherCondition c5 = factory.CreateURLContainsCondition("www.google.com");
  201. // Regex patterns and substring patterns do not share IDs.
  202. EXPECT_EQ(c5.string_pattern()->pattern(), c4.string_pattern()->pattern());
  203. EXPECT_NE(c5.string_pattern(), c4.string_pattern());
  204. EXPECT_NE(c5.string_pattern()->id(), c4.string_pattern()->id());
  205. // Check that all MatcherStringPattern singletons are freed if we call
  206. // ForgetUnusedPatterns.
  207. MatcherStringPattern::ID old_id_1 = c1.string_pattern()->id();
  208. MatcherStringPattern::ID old_id_4 = c4.string_pattern()->id();
  209. factory.ForgetUnusedPatterns(std::set<MatcherStringPattern::ID>());
  210. EXPECT_TRUE(factory.IsEmpty());
  211. URLMatcherCondition c6 = factory.CreateHostEqualsCondition("www.google.com");
  212. EXPECT_NE(old_id_1, c6.string_pattern()->id());
  213. URLMatcherCondition c7 = factory.CreateURLMatchesCondition("www.google.com");
  214. EXPECT_NE(old_id_4, c7.string_pattern()->id());
  215. }
  216. TEST(URLMatcherConditionFactoryTest, TestComponentSearches) {
  217. URLMatcherConditionFactory factory;
  218. GURL gurl(
  219. "https://www.google.com:1234/webhp?sourceid=chrome-instant&ie=UTF-8"
  220. "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome");
  221. std::string url = factory.CanonicalizeURLForComponentSearches(gurl);
  222. GURL gurl2(
  223. "https://www.google.com.:1234/webhp?sourceid=chrome-instant"
  224. "&ie=UTF-8&ion=1#hl=en&output=search&sclient=psy-ab"
  225. "&q=chrome%20is%20awesome");
  226. std::string url2 = factory.CanonicalizeURLForComponentSearches(gurl2);
  227. // Test host component.
  228. EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition(std::string()), url));
  229. EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition("www.goog"), url));
  230. EXPECT_TRUE(
  231. Matches(factory.CreateHostPrefixCondition("www.google.com"), url));
  232. EXPECT_TRUE(
  233. Matches(factory.CreateHostPrefixCondition(".www.google.com"), url));
  234. EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("google.com"), url));
  235. EXPECT_FALSE(
  236. Matches(factory.CreateHostPrefixCondition("www.google.com/"), url));
  237. EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("webhp"), url));
  238. EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(std::string()), url));
  239. EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(std::string()), url2));
  240. EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition("com"), url));
  241. EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition("com"), url2));
  242. EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(".com"), url));
  243. EXPECT_TRUE(
  244. Matches(factory.CreateHostSuffixCondition("www.google.com"), url));
  245. EXPECT_TRUE(
  246. Matches(factory.CreateHostSuffixCondition(".www.google.com"), url));
  247. EXPECT_TRUE(
  248. Matches(factory.CreateHostSuffixCondition(".www.google.com"), url2));
  249. EXPECT_TRUE(
  250. Matches(factory.CreateHostSuffixCondition(".www.google.com."), url));
  251. EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("www"), url));
  252. EXPECT_FALSE(
  253. Matches(factory.CreateHostSuffixCondition("www.google.com/"), url));
  254. EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("webhp"), url));
  255. EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition(std::string()), url));
  256. EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition("www"), url));
  257. EXPECT_TRUE(
  258. Matches(factory.CreateHostEqualsCondition("www.google.com"), url));
  259. EXPECT_TRUE(
  260. Matches(factory.CreateHostEqualsCondition("www.google.com"), url2));
  261. EXPECT_FALSE(
  262. Matches(factory.CreateHostEqualsCondition("www.google.com/"), url));
  263. EXPECT_TRUE(
  264. Matches(factory.CreateHostEqualsCondition(".www.google.com."), url));
  265. EXPECT_TRUE(
  266. Matches(factory.CreateHostEqualsCondition(".www.google.com."), url2));
  267. // Test path component.
  268. EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition(std::string()), url));
  269. EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition("/web"), url));
  270. EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition("/webhp"), url));
  271. EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("webhp"), url));
  272. EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("/webhp?"), url));
  273. EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("?sourceid"), url));
  274. EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition(std::string()), url));
  275. EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition("webhp"), url));
  276. EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition("/webhp"), url));
  277. EXPECT_FALSE(Matches(factory.CreatePathSuffixCondition("/web"), url));
  278. EXPECT_FALSE(Matches(factory.CreatePathSuffixCondition("/webhp?"), url));
  279. EXPECT_TRUE(Matches(factory.CreatePathEqualsCondition("/webhp"), url));
  280. EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("webhp"), url));
  281. EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("/webhp?"), url));
  282. EXPECT_FALSE(
  283. Matches(factory.CreatePathEqualsCondition("www.google.com"), url));
  284. // Test query component.
  285. EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition(std::string()), url));
  286. EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition("sourceid"), url));
  287. // The '?' at the beginning is just ignored.
  288. EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition("?sourceid"), url));
  289. EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition(std::string()), url));
  290. EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition("ion=1"), url));
  291. EXPECT_FALSE(Matches(factory.CreateQuerySuffixCondition("www"), url));
  292. // "Suffix" condition + pattern starting with '?' = "equals" condition.
  293. EXPECT_FALSE(Matches(factory.CreateQuerySuffixCondition(
  294. "?sourceid=chrome-instant&ie=UTF-8&ion="),
  295. url));
  296. EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition(
  297. "?sourceid=chrome-instant&ie=UTF-8&ion=1"),
  298. url));
  299. EXPECT_FALSE(Matches(factory.CreateQueryEqualsCondition(
  300. "?sourceid=chrome-instant&ie=UTF-8&ion="),
  301. url));
  302. EXPECT_FALSE(Matches(factory.CreateQueryEqualsCondition(
  303. "sourceid=chrome-instant&ie=UTF-8&ion="),
  304. url));
  305. EXPECT_TRUE(Matches(factory.CreateQueryEqualsCondition(
  306. "sourceid=chrome-instant&ie=UTF-8&ion=1"),
  307. url));
  308. // The '?' at the beginning is just ignored.
  309. EXPECT_TRUE(Matches(factory.CreateQueryEqualsCondition(
  310. "?sourceid=chrome-instant&ie=UTF-8&ion=1"),
  311. url));
  312. EXPECT_FALSE(
  313. Matches(factory.CreateQueryEqualsCondition("www.google.com"), url));
  314. // Test adjacent components
  315. EXPECT_TRUE(Matches(
  316. factory.CreateHostSuffixPathPrefixCondition("google.com", "/webhp"),
  317. url));
  318. EXPECT_TRUE(Matches(
  319. factory.CreateHostSuffixPathPrefixCondition("google.com", "/webhp"),
  320. url2));
  321. EXPECT_TRUE(Matches(
  322. factory.CreateHostSuffixPathPrefixCondition("google.com.", "/webhp"),
  323. url));
  324. EXPECT_TRUE(Matches(
  325. factory.CreateHostSuffixPathPrefixCondition("google.com.", "/webhp"),
  326. url2));
  327. EXPECT_TRUE(Matches(
  328. factory.CreateHostSuffixPathPrefixCondition(std::string(), "/webhp"),
  329. url));
  330. EXPECT_TRUE(Matches(
  331. factory.CreateHostSuffixPathPrefixCondition("google.com", std::string()),
  332. url));
  333. EXPECT_FALSE(Matches(
  334. factory.CreateHostSuffixPathPrefixCondition("www", std::string()), url));
  335. EXPECT_TRUE(Matches(
  336. factory.CreateHostEqualsPathPrefixCondition("www.google.com", "/webhp"),
  337. url));
  338. EXPECT_TRUE(Matches(
  339. factory.CreateHostEqualsPathPrefixCondition("www.google.com", "/webhp"),
  340. url2));
  341. EXPECT_TRUE(Matches(
  342. factory.CreateHostEqualsPathPrefixCondition(".www.google.com.", "/webhp"),
  343. url));
  344. EXPECT_TRUE(Matches(
  345. factory.CreateHostEqualsPathPrefixCondition(".www.google.com.", "/webhp"),
  346. url2));
  347. EXPECT_FALSE(Matches(
  348. factory.CreateHostEqualsPathPrefixCondition(std::string(), "/webhp"),
  349. url));
  350. EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition(
  351. "www.google.com", std::string()),
  352. url));
  353. EXPECT_FALSE(Matches(
  354. factory.CreateHostEqualsPathPrefixCondition("google.com", std::string()),
  355. url));
  356. }
  357. TEST(URLMatcherConditionFactoryTest, TestFullSearches) {
  358. // The Port 443 is stripped because it is the default port for https.
  359. GURL gurl(
  360. "https://www.google.com:443/webhp?sourceid=chrome-instant&ie=UTF-8"
  361. "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome");
  362. URLMatcherConditionFactory factory;
  363. std::string url = factory.CanonicalizeURLForFullSearches(gurl);
  364. EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(std::string()), url));
  365. EXPECT_TRUE(
  366. Matches(factory.CreateURLPrefixCondition("https://www.goog"), url));
  367. EXPECT_TRUE(
  368. Matches(factory.CreateURLPrefixCondition("https://www.google.com"), url));
  369. EXPECT_TRUE(Matches(
  370. factory.CreateURLPrefixCondition("https://www.google.com/webhp?"), url));
  371. EXPECT_FALSE(
  372. Matches(factory.CreateURLPrefixCondition("http://www.google.com"), url));
  373. EXPECT_FALSE(Matches(factory.CreateURLPrefixCondition("webhp"), url));
  374. EXPECT_TRUE(Matches(factory.CreateURLSuffixCondition(std::string()), url));
  375. EXPECT_TRUE(Matches(factory.CreateURLSuffixCondition("ion=1"), url));
  376. EXPECT_FALSE(Matches(factory.CreateURLSuffixCondition("www"), url));
  377. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition(std::string()), url));
  378. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("www.goog"), url));
  379. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("webhp"), url));
  380. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("?"), url));
  381. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("sourceid"), url));
  382. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("ion=1"), url));
  383. EXPECT_FALSE(Matches(factory.CreateURLContainsCondition(".www.goog"), url));
  384. EXPECT_FALSE(Matches(factory.CreateURLContainsCondition("foobar"), url));
  385. EXPECT_FALSE(Matches(factory.CreateURLContainsCondition("search"), url));
  386. EXPECT_FALSE(Matches(factory.CreateURLContainsCondition(":443"), url));
  387. EXPECT_TRUE(Matches(factory.CreateURLEqualsCondition(
  388. "https://www.google.com/"
  389. "webhp?sourceid=chrome-instant&ie=UTF-8&ion=1"),
  390. url));
  391. EXPECT_FALSE(
  392. Matches(factory.CreateURLEqualsCondition("https://www.google.com"), url));
  393. // Same as above but this time with a non-standard port.
  394. gurl = GURL(
  395. "https://www.google.com:1234/webhp?sourceid=chrome-instant&"
  396. "ie=UTF-8&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20"
  397. "awesome");
  398. url = factory.CanonicalizeURLForFullSearches(gurl);
  399. EXPECT_TRUE(Matches(
  400. factory.CreateURLPrefixCondition("https://www.google.com:1234/webhp?"),
  401. url));
  402. EXPECT_TRUE(Matches(factory.CreateURLContainsCondition(":1234"), url));
  403. }
  404. //
  405. // URLMatcherConditionSet
  406. //
  407. TEST(URLMatcherConditionSetTest, Constructor) {
  408. URLMatcherConditionFactory factory;
  409. URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com");
  410. URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo");
  411. std::set<URLMatcherCondition> conditions;
  412. conditions.insert(m1);
  413. conditions.insert(m2);
  414. scoped_refptr<URLMatcherConditionSet> condition_set(
  415. new URLMatcherConditionSet(1, conditions));
  416. EXPECT_EQ(1u, condition_set->id());
  417. EXPECT_EQ(2u, condition_set->conditions().size());
  418. }
  419. TEST(URLMatcherConditionSetTest, Matching) {
  420. GURL url1("http://www.example.com/foo?bar=1");
  421. GURL url2("http://foo.example.com/index.html");
  422. GURL url3("http://www.example.com:80/foo?bar=1");
  423. GURL url4("http://www.example.com:8080/foo?bar=1");
  424. URLMatcherConditionFactory factory;
  425. URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com");
  426. URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo");
  427. std::set<URLMatcherCondition> conditions;
  428. conditions.insert(m1);
  429. conditions.insert(m2);
  430. scoped_refptr<URLMatcherConditionSet> condition_set(
  431. new URLMatcherConditionSet(1, conditions));
  432. EXPECT_EQ(1u, condition_set->id());
  433. EXPECT_EQ(2u, condition_set->conditions().size());
  434. std::set<MatcherStringPattern::ID> matching_patterns;
  435. matching_patterns.insert(m1.string_pattern()->id());
  436. EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url1));
  437. matching_patterns.insert(m2.string_pattern()->id());
  438. EXPECT_TRUE(condition_set->IsMatch(matching_patterns, url1));
  439. EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url2));
  440. // Test scheme filters.
  441. scoped_refptr<URLMatcherConditionSet> condition_set2(
  442. new URLMatcherConditionSet(
  443. 1, conditions, std::make_unique<URLMatcherSchemeFilter>("https"),
  444. std::unique_ptr<URLMatcherPortFilter>()));
  445. EXPECT_FALSE(condition_set2->IsMatch(matching_patterns, url1));
  446. scoped_refptr<URLMatcherConditionSet> condition_set3(
  447. new URLMatcherConditionSet(
  448. 1, conditions, std::make_unique<URLMatcherSchemeFilter>("http"),
  449. std::unique_ptr<URLMatcherPortFilter>()));
  450. EXPECT_TRUE(condition_set3->IsMatch(matching_patterns, url1));
  451. // Test port filters.
  452. std::vector<URLMatcherPortFilter::Range> ranges;
  453. ranges.push_back(URLMatcherPortFilter::CreateRange(80));
  454. std::unique_ptr<URLMatcherPortFilter> filter(
  455. new URLMatcherPortFilter(ranges));
  456. scoped_refptr<URLMatcherConditionSet> condition_set4(
  457. new URLMatcherConditionSet(1, conditions,
  458. std::unique_ptr<URLMatcherSchemeFilter>(),
  459. std::move(filter)));
  460. EXPECT_TRUE(condition_set4->IsMatch(matching_patterns, url1));
  461. EXPECT_TRUE(condition_set4->IsMatch(matching_patterns, url3));
  462. EXPECT_FALSE(condition_set4->IsMatch(matching_patterns, url4));
  463. // Test regex patterns.
  464. matching_patterns.clear();
  465. URLMatcherCondition r1 = factory.CreateURLMatchesCondition("/fo?oo");
  466. std::set<URLMatcherCondition> regex_conditions;
  467. regex_conditions.insert(r1);
  468. scoped_refptr<URLMatcherConditionSet> condition_set5(
  469. new URLMatcherConditionSet(1, regex_conditions));
  470. EXPECT_FALSE(condition_set5->IsMatch(matching_patterns, url1));
  471. matching_patterns.insert(r1.string_pattern()->id());
  472. EXPECT_TRUE(condition_set5->IsMatch(matching_patterns, url1));
  473. regex_conditions.insert(m1);
  474. scoped_refptr<URLMatcherConditionSet> condition_set6(
  475. new URLMatcherConditionSet(1, regex_conditions));
  476. EXPECT_FALSE(condition_set6->IsMatch(matching_patterns, url1));
  477. matching_patterns.insert(m1.string_pattern()->id());
  478. EXPECT_TRUE(condition_set6->IsMatch(matching_patterns, url1));
  479. matching_patterns.clear();
  480. regex_conditions.clear();
  481. URLMatcherCondition r2 = factory.CreateOriginAndPathMatchesCondition("b[a]r");
  482. regex_conditions.insert(r2);
  483. scoped_refptr<URLMatcherConditionSet> condition_set7(
  484. new URLMatcherConditionSet(1, regex_conditions));
  485. EXPECT_FALSE(condition_set7->IsMatch(matching_patterns, url1));
  486. matching_patterns.insert(r2.string_pattern()->id());
  487. EXPECT_TRUE(condition_set7->IsMatch(matching_patterns, url1));
  488. }
  489. namespace {
  490. bool IsQueryMatch(
  491. const std::string& url_query,
  492. const std::string& key,
  493. URLQueryElementMatcherCondition::QueryElementType query_element_type,
  494. const std::string& value,
  495. URLQueryElementMatcherCondition::QueryValueMatchType query_value_match_type,
  496. URLQueryElementMatcherCondition::Type match_type) {
  497. URLMatcherConditionFactory factory;
  498. URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com");
  499. URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo");
  500. URLMatcherConditionSet::Conditions conditions;
  501. conditions.insert(m1);
  502. conditions.insert(m2);
  503. URLQueryElementMatcherCondition q1(key, value, query_value_match_type,
  504. query_element_type, match_type, &factory);
  505. URLMatcherConditionSet::QueryConditions query_conditions;
  506. query_conditions.insert(q1);
  507. std::unique_ptr<URLMatcherSchemeFilter> scheme_filter;
  508. std::unique_ptr<URLMatcherPortFilter> port_filter;
  509. scoped_refptr<URLMatcherConditionSet> condition_set(
  510. new URLMatcherConditionSet(1, conditions, query_conditions,
  511. std::move(scheme_filter),
  512. std::move(port_filter)));
  513. GURL url("http://www.example.com/foo?" + url_query);
  514. URLMatcher matcher;
  515. URLMatcherConditionSet::Vector vector;
  516. vector.push_back(condition_set);
  517. matcher.AddConditionSets(vector);
  518. return matcher.MatchURL(url).size() == 1;
  519. }
  520. } // namespace
  521. TEST(URLMatcherConditionSetTest, QueryMatching) {
  522. EXPECT_TRUE(IsQueryMatch(
  523. "a=foo&b=foo&a=barr", "a",
  524. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  525. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  526. URLQueryElementMatcherCondition::MATCH_ANY));
  527. EXPECT_FALSE(IsQueryMatch(
  528. "a=foo&b=foo&a=barr", "a",
  529. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  530. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  531. URLQueryElementMatcherCondition::MATCH_ANY));
  532. EXPECT_TRUE(
  533. IsQueryMatch("a=foo&b=foo&a=barr", "a",
  534. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY, "bar",
  535. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  536. URLQueryElementMatcherCondition::MATCH_ANY));
  537. EXPECT_FALSE(
  538. IsQueryMatch("a=foo&b=foo&a=barr", "a",
  539. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY, "bar",
  540. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  541. URLQueryElementMatcherCondition::MATCH_ANY));
  542. EXPECT_TRUE(IsQueryMatch(
  543. "a&b=foo&a=barr", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  544. "bar", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  545. URLQueryElementMatcherCondition::MATCH_ANY));
  546. EXPECT_FALSE(
  547. IsQueryMatch("a=foo&b=foo&a=barr", "a",
  548. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY, "bar",
  549. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  550. URLQueryElementMatcherCondition::MATCH_ANY));
  551. EXPECT_FALSE(IsQueryMatch(
  552. "a=foo&b=foo&a=bar", "a",
  553. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  554. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  555. URLQueryElementMatcherCondition::MATCH_ALL));
  556. EXPECT_TRUE(IsQueryMatch(
  557. "a=bar&b=foo&a=bar", "a",
  558. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  559. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  560. URLQueryElementMatcherCondition::MATCH_ALL));
  561. EXPECT_TRUE(IsQueryMatch(
  562. "a=bar&b=foo&a=bar", "b",
  563. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  564. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  565. URLQueryElementMatcherCondition::MATCH_ALL));
  566. EXPECT_FALSE(IsQueryMatch(
  567. "a=bar&b=foo&a=bar", "b",
  568. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "goo",
  569. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  570. URLQueryElementMatcherCondition::MATCH_ALL));
  571. EXPECT_FALSE(IsQueryMatch(
  572. "a=bar&b=foo&a=bar", "c",
  573. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "goo",
  574. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  575. URLQueryElementMatcherCondition::MATCH_ALL));
  576. EXPECT_TRUE(IsQueryMatch(
  577. "a=foo1&b=foo&a=foo2", "a",
  578. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  579. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  580. URLQueryElementMatcherCondition::MATCH_ALL));
  581. EXPECT_FALSE(IsQueryMatch(
  582. "a=foo1&b=foo&a=fo02", "a",
  583. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  584. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  585. URLQueryElementMatcherCondition::MATCH_ALL));
  586. EXPECT_TRUE(IsQueryMatch(
  587. "a&b=foo&a", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  588. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  589. URLQueryElementMatcherCondition::MATCH_ALL));
  590. EXPECT_TRUE(IsQueryMatch(
  591. "alt&b=foo", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  592. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  593. URLQueryElementMatcherCondition::MATCH_ALL));
  594. EXPECT_TRUE(IsQueryMatch(
  595. "b=foo&a", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY, "foo",
  596. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  597. URLQueryElementMatcherCondition::MATCH_ALL));
  598. EXPECT_FALSE(IsQueryMatch(
  599. "b=foo", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY, "foo",
  600. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  601. URLQueryElementMatcherCondition::MATCH_ALL));
  602. EXPECT_TRUE(IsQueryMatch(
  603. "b=foo&a", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY, "foo",
  604. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  605. URLQueryElementMatcherCondition::MATCH_ALL));
  606. EXPECT_TRUE(IsQueryMatch(
  607. "a=foo&b=foo&a=bar", "a",
  608. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  609. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  610. URLQueryElementMatcherCondition::MATCH_FIRST));
  611. EXPECT_FALSE(IsQueryMatch(
  612. "a=foo&b=foo&a=bar", "a",
  613. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  614. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  615. URLQueryElementMatcherCondition::MATCH_FIRST));
  616. EXPECT_TRUE(IsQueryMatch(
  617. "a=foo1&b=foo&a=bar", "a",
  618. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  619. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  620. URLQueryElementMatcherCondition::MATCH_FIRST));
  621. EXPECT_FALSE(IsQueryMatch(
  622. "a=foo1&b=foo&a=bar", "a",
  623. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  624. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  625. URLQueryElementMatcherCondition::MATCH_FIRST));
  626. EXPECT_TRUE(IsQueryMatch(
  627. "a&b=foo&a=bar", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  628. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  629. URLQueryElementMatcherCondition::MATCH_FIRST));
  630. EXPECT_TRUE(IsQueryMatch(
  631. "alt&b=foo&a=bar", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  632. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  633. URLQueryElementMatcherCondition::MATCH_FIRST));
  634. EXPECT_FALSE(IsQueryMatch(
  635. "alt&b=foo&a=bar", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  636. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  637. URLQueryElementMatcherCondition::MATCH_FIRST));
  638. EXPECT_FALSE(IsQueryMatch(
  639. "a=foo&b=foo&a=bar", "a",
  640. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  641. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  642. URLQueryElementMatcherCondition::MATCH_LAST));
  643. EXPECT_TRUE(IsQueryMatch(
  644. "a=foo&b=foo&a=bar", "a",
  645. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  646. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  647. URLQueryElementMatcherCondition::MATCH_LAST));
  648. EXPECT_FALSE(IsQueryMatch(
  649. "a=foo1&b=foo&a=bar", "a",
  650. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "foo",
  651. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  652. URLQueryElementMatcherCondition::MATCH_LAST));
  653. EXPECT_TRUE(IsQueryMatch(
  654. "a=foo1&b=foo&a=bar1", "a",
  655. URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE, "bar",
  656. URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  657. URLQueryElementMatcherCondition::MATCH_LAST));
  658. EXPECT_FALSE(IsQueryMatch(
  659. "a&b=foo&a=bar", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  660. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  661. URLQueryElementMatcherCondition::MATCH_LAST));
  662. EXPECT_TRUE(IsQueryMatch(
  663. "b=foo&alt", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  664. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
  665. URLQueryElementMatcherCondition::MATCH_LAST));
  666. EXPECT_FALSE(IsQueryMatch(
  667. "b=foo&alt", "a", URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
  668. "foo", URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
  669. URLQueryElementMatcherCondition::MATCH_LAST));
  670. }
  671. //
  672. // URLMatcher
  673. //
  674. TEST(URLMatcherTest, FullTest) {
  675. GURL url1("http://www.example.com/foo?bar=1");
  676. GURL url2("http://foo.example.com/index.html");
  677. URLMatcher matcher;
  678. URLMatcherConditionFactory* factory = matcher.condition_factory();
  679. // First insert.
  680. URLMatcherConditionSet::Conditions conditions1;
  681. conditions1.insert(factory->CreateHostSuffixCondition("example.com"));
  682. conditions1.insert(factory->CreatePathContainsCondition("foo"));
  683. const base::MatcherStringPattern::ID kConditionSetId1 = 1;
  684. URLMatcherConditionSet::Vector insert1;
  685. insert1.push_back(base::MakeRefCounted<URLMatcherConditionSet>(
  686. kConditionSetId1, conditions1));
  687. matcher.AddConditionSets(insert1);
  688. EXPECT_EQ(1u, matcher.MatchURL(url1).size());
  689. EXPECT_EQ(0u, matcher.MatchURL(url2).size());
  690. // Second insert.
  691. URLMatcherConditionSet::Conditions conditions2;
  692. conditions2.insert(factory->CreateHostSuffixCondition("example.com"));
  693. const base::MatcherStringPattern::ID kConditionSetId2 = 2;
  694. URLMatcherConditionSet::Vector insert2;
  695. insert2.push_back(base::MakeRefCounted<URLMatcherConditionSet>(
  696. kConditionSetId2, conditions2));
  697. matcher.AddConditionSets(insert2);
  698. EXPECT_EQ(2u, matcher.MatchURL(url1).size());
  699. EXPECT_EQ(1u, matcher.MatchURL(url2).size());
  700. // This should be the cached singleton.
  701. base::MatcherStringPattern::ID patternId1 =
  702. factory->CreateHostSuffixCondition("example.com").string_pattern()->id();
  703. // Third insert.
  704. URLMatcherConditionSet::Conditions conditions3;
  705. conditions3.insert(factory->CreateHostSuffixCondition("example.com"));
  706. conditions3.insert(factory->CreateURLMatchesCondition("x.*[0-9]"));
  707. const base::MatcherStringPattern::ID kConditionSetId3 = 3;
  708. URLMatcherConditionSet::Vector insert3;
  709. insert3.push_back(base::MakeRefCounted<URLMatcherConditionSet>(
  710. kConditionSetId3, conditions3));
  711. matcher.AddConditionSets(insert3);
  712. EXPECT_EQ(3u, matcher.MatchURL(url1).size());
  713. EXPECT_EQ(1u, matcher.MatchURL(url2).size());
  714. // Removal of third insert.
  715. std::vector<base::MatcherStringPattern::ID> remove3;
  716. remove3.push_back(kConditionSetId3);
  717. matcher.RemoveConditionSets(remove3);
  718. EXPECT_EQ(2u, matcher.MatchURL(url1).size());
  719. EXPECT_EQ(1u, matcher.MatchURL(url2).size());
  720. // Removal of second insert.
  721. std::vector<base::MatcherStringPattern::ID> remove2;
  722. remove2.push_back(kConditionSetId2);
  723. matcher.RemoveConditionSets(remove2);
  724. EXPECT_EQ(1u, matcher.MatchURL(url1).size());
  725. EXPECT_EQ(0u, matcher.MatchURL(url2).size());
  726. // Removal of first insert.
  727. std::vector<base::MatcherStringPattern::ID> remove1;
  728. remove1.push_back(kConditionSetId1);
  729. matcher.RemoveConditionSets(remove1);
  730. EXPECT_EQ(0u, matcher.MatchURL(url1).size());
  731. EXPECT_EQ(0u, matcher.MatchURL(url2).size());
  732. EXPECT_TRUE(matcher.IsEmpty());
  733. // The cached singleton in matcher.condition_factory_ should be destroyed to
  734. // free memory.
  735. base::MatcherStringPattern::ID patternId2 =
  736. factory->CreateHostSuffixCondition("example.com").string_pattern()->id();
  737. // If patternId1 and patternId2 are different that indicates that
  738. // matcher.condition_factory_ does not leak memory by holding onto
  739. // unused patterns.
  740. EXPECT_NE(patternId1, patternId2);
  741. }
  742. TEST(URLMatcherTest, TestComponentsImplyContains) {
  743. // Due to a different implementation of component (prefix, suffix and equals)
  744. // and *Contains conditions we need to check that when a pattern matches a
  745. // given part of a URL as equal, prefix or suffix, it also matches it in the
  746. // "contains" test.
  747. GURL url("https://www.google.com:1234/webhp?test=val&a=b");
  748. URLMatcher matcher;
  749. URLMatcherConditionFactory* factory = matcher.condition_factory();
  750. URLMatcherConditionSet::Conditions conditions;
  751. // First insert all the matching equals => contains pairs.
  752. conditions.insert(factory->CreateHostEqualsCondition("www.google.com"));
  753. conditions.insert(factory->CreateHostContainsCondition("www.google.com"));
  754. conditions.insert(factory->CreateHostPrefixCondition("www."));
  755. conditions.insert(factory->CreateHostContainsCondition("www."));
  756. conditions.insert(factory->CreateHostSuffixCondition("com"));
  757. conditions.insert(factory->CreateHostContainsCondition("com"));
  758. conditions.insert(factory->CreatePathEqualsCondition("/webhp"));
  759. conditions.insert(factory->CreatePathContainsCondition("/webhp"));
  760. conditions.insert(factory->CreatePathPrefixCondition("/we"));
  761. conditions.insert(factory->CreatePathContainsCondition("/we"));
  762. conditions.insert(factory->CreatePathSuffixCondition("hp"));
  763. conditions.insert(factory->CreatePathContainsCondition("hp"));
  764. conditions.insert(factory->CreateQueryEqualsCondition("test=val&a=b"));
  765. conditions.insert(factory->CreateQueryContainsCondition("test=val&a=b"));
  766. conditions.insert(factory->CreateQueryPrefixCondition("test=v"));
  767. conditions.insert(factory->CreateQueryContainsCondition("test=v"));
  768. conditions.insert(factory->CreateQuerySuffixCondition("l&a=b"));
  769. conditions.insert(factory->CreateQueryContainsCondition("l&a=b"));
  770. // The '?' for equality is just ignored.
  771. conditions.insert(factory->CreateQueryEqualsCondition("?test=val&a=b"));
  772. // Due to '?' the condition created here is a prefix-testing condition.
  773. conditions.insert(factory->CreateQueryContainsCondition("?test=val&a=b"));
  774. const base::MatcherStringPattern::ID kConditionSetId = 1;
  775. URLMatcherConditionSet::Vector insert;
  776. insert.push_back(base::MakeRefCounted<URLMatcherConditionSet>(kConditionSetId,
  777. conditions));
  778. matcher.AddConditionSets(insert);
  779. EXPECT_EQ(1u, matcher.MatchURL(url).size());
  780. }
  781. // Check that matches in everything but the query are found.
  782. TEST(URLMatcherTest, TestOriginAndPathRegExPositive) {
  783. GURL url("https://www.google.com:1234/webhp?test=val&a=b");
  784. URLMatcher matcher;
  785. URLMatcherConditionFactory* factory = matcher.condition_factory();
  786. URLMatcherConditionSet::Conditions conditions;
  787. conditions.insert(factory->CreateOriginAndPathMatchesCondition("w..hp"));
  788. const base::MatcherStringPattern::ID kConditionSetId = 1;
  789. URLMatcherConditionSet::Vector insert;
  790. insert.push_back(base::MakeRefCounted<URLMatcherConditionSet>(kConditionSetId,
  791. conditions));
  792. matcher.AddConditionSets(insert);
  793. EXPECT_EQ(1u, matcher.MatchURL(url).size());
  794. }
  795. // Check that matches in the query are ignored.
  796. TEST(URLMatcherTest, TestOriginAndPathRegExNegative) {
  797. GURL url("https://www.google.com:1234/webhp?test=val&a=b");
  798. URLMatcher matcher;
  799. URLMatcherConditionFactory* factory = matcher.condition_factory();
  800. URLMatcherConditionSet::Conditions conditions;
  801. conditions.insert(factory->CreateOriginAndPathMatchesCondition("val"));
  802. const base::MatcherStringPattern::ID kConditionSetId = 1;
  803. URLMatcherConditionSet::Vector insert;
  804. insert.push_back(base::MakeRefCounted<URLMatcherConditionSet>(kConditionSetId,
  805. conditions));
  806. matcher.AddConditionSets(insert);
  807. EXPECT_EQ(0u, matcher.MatchURL(url).size());
  808. }
  809. } // namespace url_matcher