OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/content_settings/content_settings_pattern.h" | 5 #include "chrome/browser/content_settings/content_settings_pattern.h" |
6 | 6 |
7 #include <vector> | |
8 | |
9 #include "base/string_split.h" | |
7 #include "base/string_util.h" | 10 #include "base/string_util.h" |
8 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
9 #include "chrome/browser/content_settings/content_settings_pattern_parser.h" | 12 #include "chrome/browser/content_settings/content_settings_pattern_parser.h" |
10 #include "chrome/common/url_constants.h" | 13 #include "chrome/common/url_constants.h" |
11 #include "net/base/dns_util.h" | 14 #include "net/base/dns_util.h" |
12 #include "net/base/net_util.h" | 15 #include "net/base/net_util.h" |
13 #include "googleurl/src/gurl.h" | 16 #include "googleurl/src/gurl.h" |
14 #include "googleurl/src/url_canon.h" | 17 #include "googleurl/src/url_canon.h" |
15 | 18 |
16 namespace { | 19 namespace { |
(...skipping 17 matching lines...) Expand all Loading... | |
34 return true; | 37 return true; |
35 const size_t match = sub_domain.rfind(domain); | 38 const size_t match = sub_domain.rfind(domain); |
36 if (match == std::string::npos || | 39 if (match == std::string::npos || |
37 (match > 0 && sub_domain[match - 1] != '.') || | 40 (match > 0 && sub_domain[match - 1] != '.') || |
38 (match + domain.length() != sub_domain.length())) { | 41 (match + domain.length() != sub_domain.length())) { |
39 return false; | 42 return false; |
40 } | 43 } |
41 return true; | 44 return true; |
42 } | 45 } |
43 | 46 |
47 // Compares two domain names. | |
48 int CompareDomainNames(const std::string& str1, const std::string& str2) { | |
Bernhard Bauer
2011/06/01 20:18:25
How did we sort the patterns before? How does chro
markusheintz_
2011/06/01 20:55:26
I'm sorting it:
1) per domain starting with top l
Bernhard Bauer
2011/06/02 00:03:31
Wouldn't it be sorted like this with your CL:
co
markusheintz_
2011/06/03 13:08:54
Sorry you are right of course. I guess I need prac
| |
49 std::vector<std::string> domain_name1; | |
50 std::vector<std::string> domain_name2; | |
51 | |
52 base::SplitString(str1, '.', &domain_name1); | |
53 base::SplitString(str2, '.', &domain_name2); | |
54 | |
55 int i1 = domain_name1.size() - 1; | |
56 int i2 = domain_name2.size() - 1; | |
57 int rv; | |
58 while (i1 >= 0 && i2 >= 0) { | |
59 // domain names are stored in puny code. So it's fine to use the compare | |
60 // method. | |
61 rv = domain_name1[i1].compare(domain_name2[i2]); | |
62 if (rv != 0) | |
63 return rv; | |
64 --i1; | |
65 --i2; | |
66 } | |
67 | |
68 if (i1 > i2) | |
69 return 1; | |
70 | |
71 if (i1 < i2) | |
72 return -1; | |
73 | |
74 // The domain names are identical. | |
75 return 0; | |
76 } | |
77 | |
44 typedef ContentSettingsPattern::BuilderInterface BuilderInterface; | 78 typedef ContentSettingsPattern::BuilderInterface BuilderInterface; |
45 | 79 |
46 } // namespace | 80 } // namespace |
47 | 81 |
48 // //////////////////////////////////////////////////////////////////////////// | 82 // //////////////////////////////////////////////////////////////////////////// |
49 // ContentSettingsPattern::Builder | 83 // ContentSettingsPattern::Builder |
50 // | 84 // |
51 | 85 |
52 ContentSettingsPattern::Builder::Builder() : invalid_(false) {} | 86 ContentSettingsPattern::Builder::Builder() : invalid_(false) {} |
53 | 87 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 | 370 |
337 const std::string ContentSettingsPattern::ToString() const { | 371 const std::string ContentSettingsPattern::ToString() const { |
338 if (IsValid()) | 372 if (IsValid()) |
339 return content_settings::PatternParser::ToString(parts_); | 373 return content_settings::PatternParser::ToString(parts_); |
340 else | 374 else |
341 return ""; | 375 return ""; |
342 } | 376 } |
343 | 377 |
344 ContentSettingsPattern::Relation ContentSettingsPattern::Compare( | 378 ContentSettingsPattern::Relation ContentSettingsPattern::Compare( |
345 const ContentSettingsPattern& other) const { | 379 const ContentSettingsPattern& other) const { |
346 if (this == &other) | 380 // Two invalid patterns are identical in the way they behave. They don't match |
381 // anything and are represented as an empty string. So it's fair to treat them | |
382 // as identical. | |
383 if ((this == &other) || | |
384 (!is_valid_ && !other.is_valid_)) | |
347 return IDENTITY; | 385 return IDENTITY; |
348 | 386 |
349 if (!is_valid_ || !other.is_valid_) { | 387 if (!is_valid_ && other.is_valid_) |
350 NOTREACHED(); | 388 return DISJOINT_ORDER_POST; |
Bernhard Bauer
2011/06/01 20:18:25
If we're being totally exact, it should be SUCCESS
markusheintz_
2011/06/01 20:55:26
But the intersection of the empty set with any oth
Bernhard Bauer
2011/06/02 00:03:31
My reasoning here is that the empty set is "more s
markusheintz_
2011/06/03 13:08:54
Ok.
| |
351 return DISJOINT; | 389 if (is_valid_ && !other.is_valid_) |
352 } | 390 return DISJOINT_ORDER_PRE; |
353 | 391 |
354 // If either host, port or scheme are disjoint return immediately. | 392 // If either host, port or scheme are disjoint return immediately. |
355 Relation host_relation = CompareHost(parts_, other.parts_); | 393 Relation host_relation = CompareHost(parts_, other.parts_); |
356 if (host_relation == DISJOINT) | 394 if (host_relation == DISJOINT_ORDER_PRE || |
357 return DISJOINT; | 395 host_relation == DISJOINT_ORDER_POST) |
396 return host_relation; | |
397 | |
358 Relation port_relation = ComparePort(parts_, other.parts_); | 398 Relation port_relation = ComparePort(parts_, other.parts_); |
359 if (port_relation == DISJOINT) | 399 if (port_relation == DISJOINT_ORDER_PRE || |
360 return DISJOINT; | 400 port_relation == DISJOINT_ORDER_POST) |
401 return port_relation; | |
402 | |
361 Relation scheme_relation = CompareScheme(parts_, other.parts_); | 403 Relation scheme_relation = CompareScheme(parts_, other.parts_); |
362 if (scheme_relation == DISJOINT) | 404 if (scheme_relation == DISJOINT_ORDER_PRE || |
363 return DISJOINT; | 405 scheme_relation == DISJOINT_ORDER_POST) |
406 return scheme_relation; | |
364 | 407 |
365 if (host_relation != IDENTITY) | 408 if (host_relation != IDENTITY) |
366 return host_relation; | 409 return host_relation; |
367 if (port_relation != IDENTITY) | 410 if (port_relation != IDENTITY) |
368 return port_relation; | 411 return port_relation; |
369 return scheme_relation; | 412 return scheme_relation; |
370 } | 413 } |
371 | 414 |
415 bool ContentSettingsPattern::operator==( | |
416 const ContentSettingsPattern& other) const { | |
417 return Compare(other) == IDENTITY; | |
418 } | |
419 | |
420 bool ContentSettingsPattern::operator<( | |
421 const ContentSettingsPattern& other) const { | |
422 return Compare(other) < 0 ; | |
Bernhard Bauer
2011/06/01 20:18:25
Nit: superfluous spaces.
markusheintz_
2011/06/03 13:08:54
Done in forked CL
| |
423 } | |
424 | |
425 bool ContentSettingsPattern::operator>( | |
426 const ContentSettingsPattern& other) const { | |
427 return Compare(other) > 0; | |
428 } | |
429 | |
430 bool ContentSettingsPattern::operator!=( | |
431 const ContentSettingsPattern& other) const { | |
432 Relation relation = Compare(other); | |
433 return relation == DISJOINT_ORDER_PRE || relation == DISJOINT_ORDER_POST; | |
434 } | |
435 | |
372 // static | 436 // static |
373 ContentSettingsPattern::Relation ContentSettingsPattern::CompareHost( | 437 ContentSettingsPattern::Relation ContentSettingsPattern::CompareHost( |
374 const ContentSettingsPattern::PatternParts& parts, | 438 const ContentSettingsPattern::PatternParts& parts, |
375 const ContentSettingsPattern::PatternParts& other_parts) { | 439 const ContentSettingsPattern::PatternParts& other_parts) { |
376 if (!parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { | 440 if (!parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { |
377 // Case 1: No host starts with a wild card | 441 // Case 1: No host starts with a wild card |
378 if (parts.host == other_parts.host) { | 442 int result = CompareDomainNames(parts.host, other_parts.host); |
443 if (result == 0) | |
379 return ContentSettingsPattern::IDENTITY; | 444 return ContentSettingsPattern::IDENTITY; |
380 } else { | 445 if (result < 0) |
381 return ContentSettingsPattern::DISJOINT; | 446 return ContentSettingsPattern::DISJOINT_ORDER_PRE; |
382 } | 447 return ContentSettingsPattern::DISJOINT_ORDER_POST; |
383 } else if (parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { | 448 } else if (parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { |
384 // Case 2: |host| starts with a domain wildcard and |other_host| does not | 449 // Case 2: |host| starts with a domain wildcard and |other_host| does not |
385 // start with a domain wildcard. | 450 // start with a domain wildcard. |
386 // Examples: | 451 // Examples: |
387 // "this" host: [*.]google.com | 452 // "this" host: [*.]google.com |
388 // "other" host: google.com | 453 // "other" host: google.com |
389 // | 454 // |
390 // [*.]google.com | 455 // [*.]google.com |
391 // mail.google.com | 456 // mail.google.com |
392 // | 457 // |
393 // [*.]mail.google.com | 458 // [*.]mail.google.com |
394 // google.com | 459 // google.com |
395 // | 460 // |
396 // [*.]youtube.com | 461 // [*.]youtube.com |
397 // google.de | 462 // google.de |
398 // | 463 // |
399 // [*.]youtube.com | 464 // [*.]youtube.com |
400 // mail.google.com | 465 // mail.google.com |
401 // | 466 // |
402 // * | 467 // * |
403 // google.de | 468 // google.de |
404 if (IsSubDomainOrEqual(other_parts.host, parts.host)) { | 469 if (IsSubDomainOrEqual(other_parts.host, parts.host)) { |
405 return ContentSettingsPattern::SUCCESSOR; | 470 return ContentSettingsPattern::SUCCESSOR; |
406 } else { | 471 } else { |
407 return ContentSettingsPattern::DISJOINT; | 472 if (CompareDomainNames(parts.host, other_parts.host) < 0) |
473 return ContentSettingsPattern::DISJOINT_ORDER_PRE; | |
474 return ContentSettingsPattern::DISJOINT_ORDER_POST; | |
408 } | 475 } |
409 } else if (!parts.has_domain_wildcard && other_parts.has_domain_wildcard) { | 476 } else if (!parts.has_domain_wildcard && other_parts.has_domain_wildcard) { |
410 // Case 3: |host| starts NOT with a domain wildcard and |other_host| starts | 477 // Case 3: |host| starts NOT with a domain wildcard and |other_host| starts |
411 // with a domain wildcard. | 478 // with a domain wildcard. |
412 if (IsSubDomainOrEqual(parts.host, other_parts.host)) { | 479 if (IsSubDomainOrEqual(parts.host, other_parts.host)) { |
413 return ContentSettingsPattern::PREDECESSOR; | 480 return ContentSettingsPattern::PREDECESSOR; |
414 } else { | 481 } else { |
415 return ContentSettingsPattern::DISJOINT; | 482 if (CompareDomainNames(parts.host, other_parts.host) < 0) |
483 return ContentSettingsPattern::DISJOINT_ORDER_PRE; | |
484 return ContentSettingsPattern::DISJOINT_ORDER_POST; | |
416 } | 485 } |
417 } else if (parts.has_domain_wildcard && other_parts.has_domain_wildcard) { | 486 } else if (parts.has_domain_wildcard && other_parts.has_domain_wildcard) { |
418 // Case 4: |host| and |other_host| both start with a domain wildcard. | 487 // Case 4: |host| and |other_host| both start with a domain wildcard. |
419 // Examples: | 488 // Examples: |
420 // [*.]google.com | 489 // [*.]google.com |
421 // [*.]google.com | 490 // [*.]google.com |
422 // | 491 // |
423 // [*.]google.com | 492 // [*.]google.com |
424 // [*.]mail.google.com | 493 // [*.]mail.google.com |
425 // | 494 // |
426 // [*.]youtube.com | 495 // [*.]youtube.com |
427 // [*.]google.de | 496 // [*.]google.de |
428 // | 497 // |
429 // [*.]youtube.com | 498 // [*.]youtube.com |
430 // [*.]mail.google.com | 499 // [*.]mail.google.com |
431 // | 500 // |
432 // [*.]youtube.com | 501 // [*.]youtube.com |
433 // * | 502 // * |
434 // | 503 // |
435 // * | 504 // * |
436 // [*.]youtube.com | 505 // [*.]youtube.com |
437 if (parts.host == other_parts.host) { | 506 if (parts.host == other_parts.host) { |
438 return ContentSettingsPattern::IDENTITY; | 507 return ContentSettingsPattern::IDENTITY; |
439 } else if (IsSubDomainOrEqual(other_parts.host, parts.host)) { | 508 } else if (IsSubDomainOrEqual(other_parts.host, parts.host)) { |
440 return ContentSettingsPattern::SUCCESSOR; | 509 return ContentSettingsPattern::SUCCESSOR; |
441 } else if (IsSubDomainOrEqual(parts.host, other_parts.host)) { | 510 } else if (IsSubDomainOrEqual(parts.host, other_parts.host)) { |
442 return ContentSettingsPattern::PREDECESSOR; | 511 return ContentSettingsPattern::PREDECESSOR; |
443 } else { | 512 } else { |
444 return ContentSettingsPattern::DISJOINT; | 513 if (CompareDomainNames(parts.host, other_parts.host) < 0) |
514 return ContentSettingsPattern::DISJOINT_ORDER_PRE; | |
515 return ContentSettingsPattern::DISJOINT_ORDER_POST; | |
445 } | 516 } |
446 } | 517 } |
447 | 518 |
448 NOTREACHED(); | 519 NOTREACHED(); |
449 return ContentSettingsPattern::IDENTITY; | 520 return ContentSettingsPattern::IDENTITY; |
450 } | 521 } |
451 | 522 |
452 // static | 523 // static |
453 ContentSettingsPattern::Relation ContentSettingsPattern::CompareScheme( | 524 ContentSettingsPattern::Relation ContentSettingsPattern::CompareScheme( |
454 const ContentSettingsPattern::PatternParts& parts, | 525 const ContentSettingsPattern::PatternParts& parts, |
455 const ContentSettingsPattern::PatternParts& other_parts) { | 526 const ContentSettingsPattern::PatternParts& other_parts) { |
456 if (parts.is_scheme_wildcard && !other_parts.is_scheme_wildcard) | 527 if (parts.is_scheme_wildcard && !other_parts.is_scheme_wildcard) |
457 return ContentSettingsPattern::SUCCESSOR; | 528 return ContentSettingsPattern::SUCCESSOR; |
458 if (!parts.is_scheme_wildcard && other_parts.is_scheme_wildcard) | 529 if (!parts.is_scheme_wildcard && other_parts.is_scheme_wildcard) |
459 return ContentSettingsPattern::PREDECESSOR; | 530 return ContentSettingsPattern::PREDECESSOR; |
460 if (parts.scheme != other_parts.scheme) | 531 |
461 return ContentSettingsPattern::DISJOINT; | 532 int result = parts.scheme.compare(other_parts.scheme); |
462 return ContentSettingsPattern::IDENTITY; | 533 if (result == 0) |
534 return ContentSettingsPattern::IDENTITY; | |
535 if (result > 0) | |
536 return ContentSettingsPattern::DISJOINT_ORDER_PRE; | |
537 return ContentSettingsPattern::DISJOINT_ORDER_POST; | |
463 } | 538 } |
464 | 539 |
465 // static | 540 // static |
466 ContentSettingsPattern::Relation ContentSettingsPattern::ComparePort( | 541 ContentSettingsPattern::Relation ContentSettingsPattern::ComparePort( |
467 const ContentSettingsPattern::PatternParts& parts, | 542 const ContentSettingsPattern::PatternParts& parts, |
468 const ContentSettingsPattern::PatternParts& other_parts) { | 543 const ContentSettingsPattern::PatternParts& other_parts) { |
469 if (parts.is_port_wildcard && !other_parts.is_port_wildcard) | 544 if (parts.is_port_wildcard && !other_parts.is_port_wildcard) |
470 return ContentSettingsPattern::SUCCESSOR; | 545 return ContentSettingsPattern::SUCCESSOR; |
471 if (!parts.is_port_wildcard && other_parts.is_port_wildcard) | 546 if (!parts.is_port_wildcard && other_parts.is_port_wildcard) |
472 return ContentSettingsPattern::PREDECESSOR; | 547 return ContentSettingsPattern::PREDECESSOR; |
473 if (parts.port != other_parts.port) | 548 |
474 return ContentSettingsPattern::DISJOINT; | 549 int result = parts.port.compare(other_parts.port); |
475 return ContentSettingsPattern::IDENTITY; | 550 if (result == 0) |
551 return ContentSettingsPattern::IDENTITY; | |
552 if (result > 0) | |
553 return ContentSettingsPattern::DISJOINT_ORDER_PRE; | |
554 return ContentSettingsPattern::DISJOINT_ORDER_POST; | |
476 } | 555 } |
OLD | NEW |