Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/content_settings/content_settings_pattern.cc

Issue 6969095: Allow invalid patterns for comparison; Make the compare method a order relation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: " Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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) {
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
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;
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;
423 }
424
425 bool ContentSettingsPattern::operator>(
426 const ContentSettingsPattern& other) const {
427 return Compare(other) > 0;
428 }
429
372 // static 430 // static
373 ContentSettingsPattern::Relation ContentSettingsPattern::CompareHost( 431 ContentSettingsPattern::Relation ContentSettingsPattern::CompareHost(
374 const ContentSettingsPattern::PatternParts& parts, 432 const ContentSettingsPattern::PatternParts& parts,
375 const ContentSettingsPattern::PatternParts& other_parts) { 433 const ContentSettingsPattern::PatternParts& other_parts) {
376 if (!parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { 434 if (!parts.has_domain_wildcard && !other_parts.has_domain_wildcard) {
377 // Case 1: No host starts with a wild card 435 // Case 1: No host starts with a wild card
378 if (parts.host == other_parts.host) { 436 int result = CompareDomainNames(parts.host, other_parts.host);
437 if (result == 0)
379 return ContentSettingsPattern::IDENTITY; 438 return ContentSettingsPattern::IDENTITY;
380 } else { 439 if (result < 0)
381 return ContentSettingsPattern::DISJOINT; 440 return ContentSettingsPattern::DISJOINT_ORDER_PRE;
382 } 441 return ContentSettingsPattern::DISJOINT_ORDER_POST;
383 } else if (parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { 442 } 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 443 // Case 2: |host| starts with a domain wildcard and |other_host| does not
385 // start with a domain wildcard. 444 // start with a domain wildcard.
386 // Examples: 445 // Examples:
387 // "this" host: [*.]google.com 446 // "this" host: [*.]google.com
388 // "other" host: google.com 447 // "other" host: google.com
389 // 448 //
390 // [*.]google.com 449 // [*.]google.com
391 // mail.google.com 450 // mail.google.com
392 // 451 //
393 // [*.]mail.google.com 452 // [*.]mail.google.com
394 // google.com 453 // google.com
395 // 454 //
396 // [*.]youtube.com 455 // [*.]youtube.com
397 // google.de 456 // google.de
398 // 457 //
399 // [*.]youtube.com 458 // [*.]youtube.com
400 // mail.google.com 459 // mail.google.com
401 // 460 //
402 // * 461 // *
403 // google.de 462 // google.de
404 if (IsSubDomainOrEqual(other_parts.host, parts.host)) { 463 if (IsSubDomainOrEqual(other_parts.host, parts.host)) {
405 return ContentSettingsPattern::SUCCESSOR; 464 return ContentSettingsPattern::SUCCESSOR;
406 } else { 465 } else {
407 return ContentSettingsPattern::DISJOINT; 466 if (CompareDomainNames(parts.host, other_parts.host) < 0)
467 return ContentSettingsPattern::DISJOINT_ORDER_PRE;
468 return ContentSettingsPattern::DISJOINT_ORDER_POST;
408 } 469 }
409 } else if (!parts.has_domain_wildcard && other_parts.has_domain_wildcard) { 470 } 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 471 // Case 3: |host| starts NOT with a domain wildcard and |other_host| starts
411 // with a domain wildcard. 472 // with a domain wildcard.
412 if (IsSubDomainOrEqual(parts.host, other_parts.host)) { 473 if (IsSubDomainOrEqual(parts.host, other_parts.host)) {
413 return ContentSettingsPattern::PREDECESSOR; 474 return ContentSettingsPattern::PREDECESSOR;
414 } else { 475 } else {
415 return ContentSettingsPattern::DISJOINT; 476 if (CompareDomainNames(parts.host, other_parts.host) < 0)
477 return ContentSettingsPattern::DISJOINT_ORDER_PRE;
478 return ContentSettingsPattern::DISJOINT_ORDER_POST;
416 } 479 }
417 } else if (parts.has_domain_wildcard && other_parts.has_domain_wildcard) { 480 } else if (parts.has_domain_wildcard && other_parts.has_domain_wildcard) {
418 // Case 4: |host| and |other_host| both start with a domain wildcard. 481 // Case 4: |host| and |other_host| both start with a domain wildcard.
419 // Examples: 482 // Examples:
420 // [*.]google.com 483 // [*.]google.com
421 // [*.]google.com 484 // [*.]google.com
422 // 485 //
423 // [*.]google.com 486 // [*.]google.com
424 // [*.]mail.google.com 487 // [*.]mail.google.com
425 // 488 //
426 // [*.]youtube.com 489 // [*.]youtube.com
427 // [*.]google.de 490 // [*.]google.de
428 // 491 //
429 // [*.]youtube.com 492 // [*.]youtube.com
430 // [*.]mail.google.com 493 // [*.]mail.google.com
431 // 494 //
432 // [*.]youtube.com 495 // [*.]youtube.com
433 // * 496 // *
434 // 497 //
435 // * 498 // *
436 // [*.]youtube.com 499 // [*.]youtube.com
437 if (parts.host == other_parts.host) { 500 if (parts.host == other_parts.host) {
438 return ContentSettingsPattern::IDENTITY; 501 return ContentSettingsPattern::IDENTITY;
439 } else if (IsSubDomainOrEqual(other_parts.host, parts.host)) { 502 } else if (IsSubDomainOrEqual(other_parts.host, parts.host)) {
440 return ContentSettingsPattern::SUCCESSOR; 503 return ContentSettingsPattern::SUCCESSOR;
441 } else if (IsSubDomainOrEqual(parts.host, other_parts.host)) { 504 } else if (IsSubDomainOrEqual(parts.host, other_parts.host)) {
442 return ContentSettingsPattern::PREDECESSOR; 505 return ContentSettingsPattern::PREDECESSOR;
443 } else { 506 } else {
444 return ContentSettingsPattern::DISJOINT; 507 if (CompareDomainNames(parts.host, other_parts.host) < 0)
508 return ContentSettingsPattern::DISJOINT_ORDER_PRE;
509 return ContentSettingsPattern::DISJOINT_ORDER_POST;
445 } 510 }
446 } 511 }
447 512
448 NOTREACHED(); 513 NOTREACHED();
449 return ContentSettingsPattern::IDENTITY; 514 return ContentSettingsPattern::IDENTITY;
450 } 515 }
451 516
452 // static 517 // static
453 ContentSettingsPattern::Relation ContentSettingsPattern::CompareScheme( 518 ContentSettingsPattern::Relation ContentSettingsPattern::CompareScheme(
454 const ContentSettingsPattern::PatternParts& parts, 519 const ContentSettingsPattern::PatternParts& parts,
455 const ContentSettingsPattern::PatternParts& other_parts) { 520 const ContentSettingsPattern::PatternParts& other_parts) {
456 if (parts.is_scheme_wildcard && !other_parts.is_scheme_wildcard) 521 if (parts.is_scheme_wildcard && !other_parts.is_scheme_wildcard)
457 return ContentSettingsPattern::SUCCESSOR; 522 return ContentSettingsPattern::SUCCESSOR;
458 if (!parts.is_scheme_wildcard && other_parts.is_scheme_wildcard) 523 if (!parts.is_scheme_wildcard && other_parts.is_scheme_wildcard)
459 return ContentSettingsPattern::PREDECESSOR; 524 return ContentSettingsPattern::PREDECESSOR;
460 if (parts.scheme != other_parts.scheme) 525
461 return ContentSettingsPattern::DISJOINT; 526 int result = parts.scheme.compare(other_parts.scheme);
462 return ContentSettingsPattern::IDENTITY; 527 if (result == 0)
528 return ContentSettingsPattern::IDENTITY;
529 if (result > 0)
530 return ContentSettingsPattern::DISJOINT_ORDER_PRE;
531 return ContentSettingsPattern::DISJOINT_ORDER_POST;
463 } 532 }
464 533
465 // static 534 // static
466 ContentSettingsPattern::Relation ContentSettingsPattern::ComparePort( 535 ContentSettingsPattern::Relation ContentSettingsPattern::ComparePort(
467 const ContentSettingsPattern::PatternParts& parts, 536 const ContentSettingsPattern::PatternParts& parts,
468 const ContentSettingsPattern::PatternParts& other_parts) { 537 const ContentSettingsPattern::PatternParts& other_parts) {
469 if (parts.is_port_wildcard && !other_parts.is_port_wildcard) 538 if (parts.is_port_wildcard && !other_parts.is_port_wildcard)
470 return ContentSettingsPattern::SUCCESSOR; 539 return ContentSettingsPattern::SUCCESSOR;
471 if (!parts.is_port_wildcard && other_parts.is_port_wildcard) 540 if (!parts.is_port_wildcard && other_parts.is_port_wildcard)
472 return ContentSettingsPattern::PREDECESSOR; 541 return ContentSettingsPattern::PREDECESSOR;
473 if (parts.port != other_parts.port) 542
474 return ContentSettingsPattern::DISJOINT; 543 int result = parts.port.compare(other_parts.port);
475 return ContentSettingsPattern::IDENTITY; 544 if (result == 0)
545 return ContentSettingsPattern::IDENTITY;
546 if (result > 0)
547 return ContentSettingsPattern::DISJOINT_ORDER_PRE;
548 return ContentSettingsPattern::DISJOINT_ORDER_POST;
476 } 549 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698