OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <map> | 9 #include <map> |
10 | 10 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 #include "third_party/icu/source/i18n/unicode/datefmt.h" | 76 #include "third_party/icu/source/i18n/unicode/datefmt.h" |
77 #include "third_party/icu/source/i18n/unicode/regex.h" | 77 #include "third_party/icu/source/i18n/unicode/regex.h" |
78 #include "third_party/icu/source/i18n/unicode/ulocdata.h" | 78 #include "third_party/icu/source/i18n/unicode/ulocdata.h" |
79 | 79 |
80 using base::Time; | 80 using base::Time; |
81 | 81 |
82 namespace net { | 82 namespace net { |
83 | 83 |
84 namespace { | 84 namespace { |
85 | 85 |
| 86 typedef std::vector<size_t> Offsets; |
| 87 |
86 // what we prepend to get a file URL | 88 // what we prepend to get a file URL |
87 static const base::FilePath::CharType kFileURLPrefix[] = | 89 static const base::FilePath::CharType kFileURLPrefix[] = |
88 FILE_PATH_LITERAL("file:///"); | 90 FILE_PATH_LITERAL("file:///"); |
89 | 91 |
90 // The general list of blocked ports. Will be blocked unless a specific | 92 // The general list of blocked ports. Will be blocked unless a specific |
91 // protocol overrides it. (Ex: ftp can use ports 20 and 21) | 93 // protocol overrides it. (Ex: ftp can use ports 20 and 21) |
92 static const int kRestrictedPorts[] = { | 94 static const int kRestrictedPorts[] = { |
93 1, // tcpmux | 95 1, // tcpmux |
94 7, // echo | 96 7, // echo |
95 9, // discard | 97 9, // discard |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 out->resize(original_length); | 440 out->resize(original_length); |
439 } | 441 } |
440 | 442 |
441 // We get here with no IDN or on error, in which case we just append the | 443 // We get here with no IDN or on error, in which case we just append the |
442 // literal input. | 444 // literal input. |
443 out->append(comp, comp_len); | 445 out->append(comp, comp_len); |
444 return false; | 446 return false; |
445 } | 447 } |
446 | 448 |
447 // Clamps the offsets in |offsets_for_adjustment| to the length of |str|. | 449 // Clamps the offsets in |offsets_for_adjustment| to the length of |str|. |
448 void LimitOffsets(const base::string16& str, | 450 void LimitOffsets(const base::string16& str, Offsets* offsets_for_adjustment) { |
449 std::vector<size_t>* offsets_for_adjustment) { | |
450 if (offsets_for_adjustment) { | 451 if (offsets_for_adjustment) { |
451 std::for_each(offsets_for_adjustment->begin(), | 452 std::for_each(offsets_for_adjustment->begin(), |
452 offsets_for_adjustment->end(), | 453 offsets_for_adjustment->end(), |
453 base::LimitOffset<base::string16>(str.length())); | 454 base::LimitOffset<base::string16>(str.length())); |
454 } | 455 } |
455 } | 456 } |
456 | 457 |
457 // TODO(brettw) bug 734373: check the scripts for each host component and | 458 // TODO(brettw) bug 734373: check the scripts for each host component and |
458 // don't un-IDN-ize if there is more than one. Alternatively, only IDN for | 459 // don't un-IDN-ize if there is more than one. Alternatively, only IDN for |
459 // scripts that the user has installed. For now, just put the entire | 460 // scripts that the user has installed. For now, just put the entire |
460 // path through IDN. Maybe this feature can be implemented in ICU itself? | 461 // path through IDN. Maybe this feature can be implemented in ICU itself? |
461 // | 462 // |
462 // We may want to skip this step in the case of file URLs to allow unicode | 463 // We may want to skip this step in the case of file URLs to allow unicode |
463 // UNC hostnames regardless of encodings. | 464 // UNC hostnames regardless of encodings. |
464 base::string16 IDNToUnicodeWithOffsets( | 465 base::string16 IDNToUnicodeWithOffsets(const std::string& host, |
465 const std::string& host, | 466 const std::string& languages, |
466 const std::string& languages, | 467 Offsets* offsets_for_adjustment) { |
467 std::vector<size_t>* offsets_for_adjustment) { | |
468 // Convert the ASCII input to a base::string16 for ICU. | 468 // Convert the ASCII input to a base::string16 for ICU. |
469 base::string16 input16; | 469 base::string16 input16; |
470 input16.reserve(host.length()); | 470 input16.reserve(host.length()); |
471 input16.insert(input16.end(), host.begin(), host.end()); | 471 input16.insert(input16.end(), host.begin(), host.end()); |
472 | 472 |
473 // Do each component of the host separately, since we enforce script matching | 473 // Do each component of the host separately, since we enforce script matching |
474 // on a per-component basis. | 474 // on a per-component basis. |
475 base::string16 out16; | 475 base::string16 out16; |
476 { | 476 { |
477 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); | 477 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); |
(...skipping 23 matching lines...) Expand all Loading... |
501 // Need to add the dot we just found (if we found one). | 501 // Need to add the dot we just found (if we found one). |
502 if (component_end < input16.length()) | 502 if (component_end < input16.length()) |
503 out16.push_back('.'); | 503 out16.push_back('.'); |
504 } | 504 } |
505 } | 505 } |
506 | 506 |
507 LimitOffsets(out16, offsets_for_adjustment); | 507 LimitOffsets(out16, offsets_for_adjustment); |
508 return out16; | 508 return out16; |
509 } | 509 } |
510 | 510 |
511 // Transforms |original_offsets| by subtracting |component_begin| from all | 511 // Called after transforming a component to set all affected elements in |
512 // offsets. Any offset which was not at least this large to begin with is set | 512 // |offsets_for_adjustment| to the correct new values. |original_offsets| |
513 // to std::string::npos. | 513 // represents the offsets before the transform; |original_component_begin| and |
514 std::vector<size_t> OffsetsIntoComponent( | 514 // |original_component_end| represent the pre-transform boundaries of the |
515 const std::vector<size_t>& original_offsets, | 515 // affected component. |transformed_offsets| should be a vector created by |
516 size_t component_begin) { | 516 // adjusting |original_offsets| to be relative to the beginning of the component |
517 DCHECK_NE(std::string::npos, component_begin); | 517 // in question (via an OffsetAdjuster) and then transformed along with the |
518 std::vector<size_t> offsets_into_component(original_offsets); | 518 // component. Note that any elements in this vector which didn't originally |
519 for (std::vector<size_t>::iterator i(offsets_into_component.begin()); | 519 // point into the component may contain arbitrary values and should be ignored. |
520 i != offsets_into_component.end(); ++i) { | 520 // |transformed_component_begin| and |transformed_component_end| are the |
521 if (*i != std::string::npos) | 521 // endpoints of the transformed component and are used in combination with the |
522 *i = (*i < component_begin) ? std::string::npos : (*i - component_begin); | 522 // two offset vectors to calculate the resulting absolute offsets, which are |
523 } | 523 // stored in |offsets_for_adjustment|. |
524 return offsets_into_component; | 524 void AdjustForComponentTransform(const Offsets& original_offsets, |
525 } | 525 size_t original_component_begin, |
| 526 size_t original_component_end, |
| 527 const Offsets& transformed_offsets, |
| 528 size_t transformed_component_begin, |
| 529 size_t transformed_component_end, |
| 530 Offsets* offsets_for_adjustment) { |
| 531 if (!offsets_for_adjustment) |
| 532 return; // Nothing to do. |
526 | 533 |
527 // Called after we transform a component and append it to an output string. | 534 for (size_t i = 0; i < original_offsets.size(); ++i) { |
528 // Maps |transformed_offsets|, which represent offsets into the transformed | |
529 // component itself, into appropriate offsets for the output string, by adding | |
530 // |output_component_begin| to each. Determines which offsets need mapping by | |
531 // checking to see which of the |original_offsets| were within the designated | |
532 // original component, using its provided endpoints. | |
533 void AdjustForComponentTransform( | |
534 const std::vector<size_t>& original_offsets, | |
535 size_t original_component_begin, | |
536 size_t original_component_end, | |
537 const std::vector<size_t>& transformed_offsets, | |
538 size_t output_component_begin, | |
539 std::vector<size_t>* offsets_for_adjustment) { | |
540 if (!offsets_for_adjustment) | |
541 return; | |
542 | |
543 DCHECK_NE(std::string::npos, original_component_begin); | |
544 DCHECK_NE(std::string::npos, original_component_end); | |
545 DCHECK_NE(base::string16::npos, output_component_begin); | |
546 size_t offsets_size = offsets_for_adjustment->size(); | |
547 DCHECK_EQ(offsets_size, original_offsets.size()); | |
548 DCHECK_EQ(offsets_size, transformed_offsets.size()); | |
549 for (size_t i = 0; i < offsets_size; ++i) { | |
550 size_t original_offset = original_offsets[i]; | 535 size_t original_offset = original_offsets[i]; |
551 if ((original_offset >= original_component_begin) && | 536 if ((original_offset >= original_component_begin) && |
552 (original_offset < original_component_end)) { | 537 (original_offset < original_component_end)) { |
| 538 // This offset originally pointed into the transformed component. |
| 539 // Adjust the transformed relative offset by the new beginning point of |
| 540 // the transformed component. |
553 size_t transformed_offset = transformed_offsets[i]; | 541 size_t transformed_offset = transformed_offsets[i]; |
554 (*offsets_for_adjustment)[i] = | 542 (*offsets_for_adjustment)[i] = |
555 (transformed_offset == base::string16::npos) ? | 543 (transformed_offset == base::string16::npos) ? |
556 base::string16::npos : (output_component_begin + transformed_offset); | 544 base::string16::npos : |
| 545 (transformed_offset + transformed_component_begin); |
| 546 } else if ((original_offset >= original_component_end) && |
| 547 (original_offset != std::string::npos)) { |
| 548 // This offset pointed after the transformed component. Adjust the |
| 549 // original absolute offset by the difference between the new and old |
| 550 // component lengths. |
| 551 (*offsets_for_adjustment)[i] = |
| 552 original_offset - original_component_end + transformed_component_end; |
557 } | 553 } |
558 } | 554 } |
559 } | 555 } |
560 | 556 |
561 // If |component| is valid, its begin is incremented by |delta|. | 557 // If |component| is valid, its begin is incremented by |delta|. |
562 void AdjustComponent(int delta, url_parse::Component* component) { | 558 void AdjustComponent(int delta, url_parse::Component* component) { |
563 if (!component->is_valid()) | 559 if (!component->is_valid()) |
564 return; | 560 return; |
565 | 561 |
566 DCHECK(delta >= 0 || component->begin >= -delta); | 562 DCHECK(delta >= 0 || component->begin >= -delta); |
567 component->begin += delta; | 563 component->begin += delta; |
568 } | 564 } |
569 | 565 |
570 // Adjusts all the components of |parsed| by |delta|, except for the scheme. | 566 // Adjusts all the components of |parsed| by |delta|, except for the scheme. |
571 void AdjustComponents(int delta, url_parse::Parsed* parsed) { | 567 void AdjustAllComponentsButScheme(int delta, url_parse::Parsed* parsed) { |
572 AdjustComponent(delta, &(parsed->username)); | 568 AdjustComponent(delta, &(parsed->username)); |
573 AdjustComponent(delta, &(parsed->password)); | 569 AdjustComponent(delta, &(parsed->password)); |
574 AdjustComponent(delta, &(parsed->host)); | 570 AdjustComponent(delta, &(parsed->host)); |
575 AdjustComponent(delta, &(parsed->port)); | 571 AdjustComponent(delta, &(parsed->port)); |
576 AdjustComponent(delta, &(parsed->path)); | 572 AdjustComponent(delta, &(parsed->path)); |
577 AdjustComponent(delta, &(parsed->query)); | 573 AdjustComponent(delta, &(parsed->query)); |
578 AdjustComponent(delta, &(parsed->ref)); | 574 AdjustComponent(delta, &(parsed->ref)); |
579 } | 575 } |
580 | 576 |
581 // Helper for FormatUrlWithOffsets(). | 577 // Helper for FormatUrlWithOffsets(). |
582 base::string16 FormatViewSourceUrl( | 578 base::string16 FormatViewSourceUrl(const GURL& url, |
583 const GURL& url, | 579 const Offsets& original_offsets, |
584 const std::vector<size_t>& original_offsets, | 580 const std::string& languages, |
585 const std::string& languages, | 581 FormatUrlTypes format_types, |
586 FormatUrlTypes format_types, | 582 UnescapeRule::Type unescape_rules, |
587 UnescapeRule::Type unescape_rules, | 583 url_parse::Parsed* new_parsed, |
588 url_parse::Parsed* new_parsed, | 584 size_t* prefix_end, |
589 size_t* prefix_end, | 585 Offsets* offsets_for_adjustment) { |
590 std::vector<size_t>* offsets_for_adjustment) { | |
591 DCHECK(new_parsed); | 586 DCHECK(new_parsed); |
592 const char kViewSource[] = "view-source:"; | 587 const char kViewSource[] = "view-source:"; |
593 const size_t kViewSourceLength = arraysize(kViewSource) - 1; | 588 const size_t kViewSourceLength = arraysize(kViewSource) - 1; |
594 std::vector<size_t> offsets_into_url( | |
595 OffsetsIntoComponent(original_offsets, kViewSourceLength)); | |
596 | 589 |
597 GURL real_url(url.possibly_invalid_spec().substr(kViewSourceLength)); | 590 // Format the underlying URL and adjust offsets. |
| 591 const std::string& url_str(url.possibly_invalid_spec()); |
| 592 Offsets offsets_into_underlying_url(original_offsets); |
| 593 { |
| 594 base::OffsetAdjuster adjuster(&offsets_into_underlying_url); |
| 595 adjuster.Add(base::OffsetAdjuster::Adjustment(0, kViewSourceLength, 0)); |
| 596 } |
598 base::string16 result(ASCIIToUTF16(kViewSource) + | 597 base::string16 result(ASCIIToUTF16(kViewSource) + |
599 FormatUrlWithOffsets(real_url, languages, format_types, unescape_rules, | 598 FormatUrlWithOffsets(GURL(url_str.substr(kViewSourceLength)), languages, |
600 new_parsed, prefix_end, &offsets_into_url)); | 599 format_types, unescape_rules, new_parsed, prefix_end, |
| 600 &offsets_into_underlying_url)); |
| 601 AdjustForComponentTransform(original_offsets, kViewSourceLength, |
| 602 url_str.length(), offsets_into_underlying_url, |
| 603 kViewSourceLength, result.length(), |
| 604 offsets_for_adjustment); |
| 605 LimitOffsets(result, offsets_for_adjustment); |
601 | 606 |
602 // Adjust position values. | 607 // Adjust positions of the parsed components. |
603 if (new_parsed->scheme.is_nonempty()) { | 608 if (new_parsed->scheme.is_nonempty()) { |
604 // Assume "view-source:real-scheme" as a scheme. | 609 // Assume "view-source:real-scheme" as a scheme. |
605 new_parsed->scheme.len += kViewSourceLength; | 610 new_parsed->scheme.len += kViewSourceLength; |
606 } else { | 611 } else { |
607 new_parsed->scheme.begin = 0; | 612 new_parsed->scheme.begin = 0; |
608 new_parsed->scheme.len = kViewSourceLength - 1; | 613 new_parsed->scheme.len = kViewSourceLength - 1; |
609 } | 614 } |
610 AdjustComponents(kViewSourceLength, new_parsed); | 615 AdjustAllComponentsButScheme(kViewSourceLength, new_parsed); |
| 616 |
611 if (prefix_end) | 617 if (prefix_end) |
612 *prefix_end += kViewSourceLength; | 618 *prefix_end += kViewSourceLength; |
613 AdjustForComponentTransform(original_offsets, kViewSourceLength, | 619 |
614 url.possibly_invalid_spec().length(), offsets_into_url, kViewSourceLength, | |
615 offsets_for_adjustment); | |
616 LimitOffsets(result, offsets_for_adjustment); | |
617 return result; | 620 return result; |
618 } | 621 } |
619 | 622 |
620 class AppendComponentTransform { | 623 class AppendComponentTransform { |
621 public: | 624 public: |
622 AppendComponentTransform() {} | 625 AppendComponentTransform() {} |
623 virtual ~AppendComponentTransform() {} | 626 virtual ~AppendComponentTransform() {} |
624 | 627 |
625 virtual base::string16 Execute( | 628 virtual base::string16 Execute(const std::string& component_text, |
626 const std::string& component_text, | 629 Offsets* offsets_into_component) const = 0; |
627 std::vector<size_t>* offsets_into_component) const = 0; | |
628 | 630 |
629 // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an | 631 // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an |
630 // accessible copy constructor in order to call AppendFormattedComponent() | 632 // accessible copy constructor in order to call AppendFormattedComponent() |
631 // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ). | 633 // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ). |
632 }; | 634 }; |
633 | 635 |
634 class HostComponentTransform : public AppendComponentTransform { | 636 class HostComponentTransform : public AppendComponentTransform { |
635 public: | 637 public: |
636 explicit HostComponentTransform(const std::string& languages) | 638 explicit HostComponentTransform(const std::string& languages) |
637 : languages_(languages) { | 639 : languages_(languages) { |
638 } | 640 } |
639 | 641 |
640 private: | 642 private: |
641 virtual base::string16 Execute( | 643 virtual base::string16 Execute( |
642 const std::string& component_text, | 644 const std::string& component_text, |
643 std::vector<size_t>* offsets_into_component) const OVERRIDE { | 645 Offsets* offsets_into_component) const OVERRIDE { |
644 return IDNToUnicodeWithOffsets(component_text, languages_, | 646 return IDNToUnicodeWithOffsets(component_text, languages_, |
645 offsets_into_component); | 647 offsets_into_component); |
646 } | 648 } |
647 | 649 |
648 const std::string& languages_; | 650 const std::string& languages_; |
649 }; | 651 }; |
650 | 652 |
651 class NonHostComponentTransform : public AppendComponentTransform { | 653 class NonHostComponentTransform : public AppendComponentTransform { |
652 public: | 654 public: |
653 explicit NonHostComponentTransform(UnescapeRule::Type unescape_rules) | 655 explicit NonHostComponentTransform(UnescapeRule::Type unescape_rules) |
654 : unescape_rules_(unescape_rules) { | 656 : unescape_rules_(unescape_rules) { |
655 } | 657 } |
656 | 658 |
657 private: | 659 private: |
658 virtual base::string16 Execute( | 660 virtual base::string16 Execute( |
659 const std::string& component_text, | 661 const std::string& component_text, |
660 std::vector<size_t>* offsets_into_component) const OVERRIDE { | 662 Offsets* offsets_into_component) const OVERRIDE { |
661 return (unescape_rules_ == UnescapeRule::NONE) ? | 663 return (unescape_rules_ == UnescapeRule::NONE) ? |
662 base::UTF8ToUTF16AndAdjustOffsets(component_text, | 664 base::UTF8ToUTF16AndAdjustOffsets(component_text, |
663 offsets_into_component) : | 665 offsets_into_component) : |
664 UnescapeAndDecodeUTF8URLComponentWithOffsets(component_text, | 666 UnescapeAndDecodeUTF8URLComponentWithOffsets(component_text, |
665 unescape_rules_, offsets_into_component); | 667 unescape_rules_, offsets_into_component); |
666 } | 668 } |
667 | 669 |
668 const UnescapeRule::Type unescape_rules_; | 670 const UnescapeRule::Type unescape_rules_; |
669 }; | 671 }; |
670 | 672 |
| 673 // Transforms the portion of |spec| covered by |original_component| according to |
| 674 // |transform|. Appends the result to |output|. If |output_component| is |
| 675 // non-NULL, its start and length are set to the transformed component's new |
| 676 // start and length. For each element in |original_offsets| which is at least |
| 677 // as large as original_component.begin, the corresponding element of |
| 678 // |offsets_for_adjustment| is transformed appropriately. |
671 void AppendFormattedComponent(const std::string& spec, | 679 void AppendFormattedComponent(const std::string& spec, |
672 const url_parse::Component& original_component, | 680 const url_parse::Component& original_component, |
673 const std::vector<size_t>& original_offsets, | 681 const Offsets& original_offsets, |
674 const AppendComponentTransform& transform, | 682 const AppendComponentTransform& transform, |
675 base::string16* output, | 683 base::string16* output, |
676 url_parse::Component* output_component, | 684 url_parse::Component* output_component, |
677 std::vector<size_t>* offsets_for_adjustment) { | 685 Offsets* offsets_for_adjustment) { |
678 DCHECK(output); | 686 DCHECK(output); |
679 if (original_component.is_nonempty()) { | 687 if (original_component.is_nonempty()) { |
680 size_t original_component_begin = | 688 size_t original_component_begin = |
681 static_cast<size_t>(original_component.begin); | 689 static_cast<size_t>(original_component.begin); |
682 size_t output_component_begin = output->length(); | 690 size_t output_component_begin = output->length(); |
683 if (output_component) | 691 std::string component_str(spec, original_component_begin, |
| 692 static_cast<size_t>(original_component.len)); |
| 693 |
| 694 // Transform |component_str| and adjust the offsets accordingly. |
| 695 Offsets offsets_into_component(original_offsets); |
| 696 { |
| 697 base::OffsetAdjuster adjuster(&offsets_into_component); |
| 698 adjuster.Add(base::OffsetAdjuster::Adjustment(0, original_component_begin, |
| 699 0)); |
| 700 } |
| 701 output->append(transform.Execute(component_str, &offsets_into_component)); |
| 702 AdjustForComponentTransform(original_offsets, original_component_begin, |
| 703 static_cast<size_t>(original_component.end()), |
| 704 offsets_into_component, output_component_begin, |
| 705 output->length(), offsets_for_adjustment); |
| 706 |
| 707 // Set positions of the parsed component. |
| 708 if (output_component) { |
684 output_component->begin = static_cast<int>(output_component_begin); | 709 output_component->begin = static_cast<int>(output_component_begin); |
685 | |
686 std::vector<size_t> offsets_into_component = | |
687 OffsetsIntoComponent(original_offsets, original_component_begin); | |
688 output->append(transform.Execute(std::string(spec, original_component_begin, | |
689 static_cast<size_t>(original_component.len)), &offsets_into_component)); | |
690 | |
691 if (output_component) { | |
692 output_component->len = | 710 output_component->len = |
693 static_cast<int>(output->length() - output_component_begin); | 711 static_cast<int>(output->length() - output_component_begin); |
694 } | 712 } |
695 AdjustForComponentTransform(original_offsets, original_component_begin, | |
696 static_cast<size_t>(original_component.end()), | |
697 offsets_into_component, output_component_begin, | |
698 offsets_for_adjustment); | |
699 } else if (output_component) { | 713 } else if (output_component) { |
700 output_component->reset(); | 714 output_component->reset(); |
701 } | 715 } |
702 } | 716 } |
703 | 717 |
704 void SanitizeGeneratedFileName(base::FilePath::StringType* filename, | 718 void SanitizeGeneratedFileName(base::FilePath::StringType* filename, |
705 bool replace_trailing) { | 719 bool replace_trailing) { |
706 const base::FilePath::CharType kReplace[] = FILE_PATH_LITERAL("-"); | 720 const base::FilePath::CharType kReplace[] = FILE_PATH_LITERAL("-"); |
707 if (filename->empty()) | 721 if (filename->empty()) |
708 return; | 722 return; |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags, NULL); | 1644 *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags, NULL); |
1631 } | 1645 } |
1632 | 1646 |
1633 std::string GetHostOrSpecFromURL(const GURL& url) { | 1647 std::string GetHostOrSpecFromURL(const GURL& url) { |
1634 return url.has_host() ? TrimEndingDot(url.host()) : url.spec(); | 1648 return url.has_host() ? TrimEndingDot(url.host()) : url.spec(); |
1635 } | 1649 } |
1636 | 1650 |
1637 void AppendFormattedHost(const GURL& url, | 1651 void AppendFormattedHost(const GURL& url, |
1638 const std::string& languages, | 1652 const std::string& languages, |
1639 base::string16* output) { | 1653 base::string16* output) { |
1640 std::vector<size_t> offsets; | 1654 Offsets offsets; |
1641 AppendFormattedComponent(url.possibly_invalid_spec(), | 1655 AppendFormattedComponent(url.possibly_invalid_spec(), |
1642 url.parsed_for_possibly_invalid_spec().host, offsets, | 1656 url.parsed_for_possibly_invalid_spec().host, offsets, |
1643 HostComponentTransform(languages), output, NULL, NULL); | 1657 HostComponentTransform(languages), output, NULL, NULL); |
1644 } | 1658 } |
1645 | 1659 |
1646 base::string16 FormatUrlWithOffsets( | 1660 base::string16 FormatUrlWithOffsets( |
1647 const GURL& url, | 1661 const GURL& url, |
1648 const std::string& languages, | 1662 const std::string& languages, |
1649 FormatUrlTypes format_types, | 1663 FormatUrlTypes format_types, |
1650 UnescapeRule::Type unescape_rules, | 1664 UnescapeRule::Type unescape_rules, |
1651 url_parse::Parsed* new_parsed, | 1665 url_parse::Parsed* new_parsed, |
1652 size_t* prefix_end, | 1666 size_t* prefix_end, |
1653 std::vector<size_t>* offsets_for_adjustment) { | 1667 Offsets* offsets_for_adjustment) { |
1654 url_parse::Parsed parsed_temp; | 1668 url_parse::Parsed parsed_temp; |
1655 if (!new_parsed) | 1669 if (!new_parsed) |
1656 new_parsed = &parsed_temp; | 1670 new_parsed = &parsed_temp; |
1657 else | 1671 else |
1658 *new_parsed = url_parse::Parsed(); | 1672 *new_parsed = url_parse::Parsed(); |
1659 std::vector<size_t> original_offsets; | 1673 Offsets original_offsets; |
1660 if (offsets_for_adjustment) | 1674 if (offsets_for_adjustment) |
1661 original_offsets = *offsets_for_adjustment; | 1675 original_offsets = *offsets_for_adjustment; |
1662 | 1676 |
1663 // Special handling for view-source:. Don't use content::kViewSourceScheme | 1677 // Special handling for view-source:. Don't use content::kViewSourceScheme |
1664 // because this library shouldn't depend on chrome. | 1678 // because this library shouldn't depend on chrome. |
1665 const char* const kViewSource = "view-source"; | 1679 const char* const kViewSource = "view-source"; |
1666 // Reject "view-source:view-source:..." to avoid deep recursion. | 1680 // Reject "view-source:view-source:..." to avoid deep recursion. |
1667 const char* const kViewSourceTwice = "view-source:view-source:"; | 1681 const char* const kViewSourceTwice = "view-source:view-source:"; |
1668 if (url.SchemeIs(kViewSource) && | 1682 if (url.SchemeIs(kViewSource) && |
1669 !StartsWithASCII(url.possibly_invalid_spec(), kViewSourceTwice, false)) { | 1683 !StartsWithASCII(url.possibly_invalid_spec(), kViewSourceTwice, false)) { |
1670 return FormatViewSourceUrl(url, original_offsets, languages, format_types, | 1684 return FormatViewSourceUrl(url, original_offsets, languages, format_types, |
1671 unescape_rules, new_parsed, prefix_end, offsets_for_adjustment); | 1685 unescape_rules, new_parsed, prefix_end, |
| 1686 offsets_for_adjustment); |
1672 } | 1687 } |
1673 | 1688 |
1674 // We handle both valid and invalid URLs (this will give us the spec | 1689 // We handle both valid and invalid URLs (this will give us the spec |
1675 // regardless of validity). | 1690 // regardless of validity). |
1676 const std::string& spec = url.possibly_invalid_spec(); | 1691 const std::string& spec = url.possibly_invalid_spec(); |
1677 const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); | 1692 const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); |
1678 | 1693 |
1679 // Scheme & separators. These are ASCII. | 1694 // Scheme & separators. These are ASCII. |
1680 base::string16 url_string; | 1695 base::string16 url_string; |
1681 url_string.insert(url_string.end(), spec.begin(), | 1696 url_string.insert(url_string.end(), spec.begin(), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 // username/password. | 1734 // username/password. |
1720 offset_adjuster.Add(base::OffsetAdjuster::Adjustment( | 1735 offset_adjuster.Add(base::OffsetAdjuster::Adjustment( |
1721 static_cast<size_t>(nonempty_component->begin), | 1736 static_cast<size_t>(nonempty_component->begin), |
1722 static_cast<size_t>(nonempty_component->len + 1), 0)); | 1737 static_cast<size_t>(nonempty_component->len + 1), 0)); |
1723 } | 1738 } |
1724 } | 1739 } |
1725 } else { | 1740 } else { |
1726 AppendFormattedComponent(spec, parsed.username, original_offsets, | 1741 AppendFormattedComponent(spec, parsed.username, original_offsets, |
1727 NonHostComponentTransform(unescape_rules), &url_string, | 1742 NonHostComponentTransform(unescape_rules), &url_string, |
1728 &new_parsed->username, offsets_for_adjustment); | 1743 &new_parsed->username, offsets_for_adjustment); |
1729 if (parsed.password.is_valid()) { | 1744 if (parsed.password.is_valid()) |
1730 size_t colon = parsed.username.end(); | |
1731 DCHECK_EQ(static_cast<size_t>(parsed.password.begin - 1), colon); | |
1732 std::vector<size_t>::const_iterator colon_iter = | |
1733 std::find(original_offsets.begin(), original_offsets.end(), colon); | |
1734 if (colon_iter != original_offsets.end()) { | |
1735 (*offsets_for_adjustment)[colon_iter - original_offsets.begin()] = | |
1736 url_string.length(); | |
1737 } | |
1738 url_string.push_back(':'); | 1745 url_string.push_back(':'); |
1739 } | |
1740 AppendFormattedComponent(spec, parsed.password, original_offsets, | 1746 AppendFormattedComponent(spec, parsed.password, original_offsets, |
1741 NonHostComponentTransform(unescape_rules), &url_string, | 1747 NonHostComponentTransform(unescape_rules), &url_string, |
1742 &new_parsed->password, offsets_for_adjustment); | 1748 &new_parsed->password, offsets_for_adjustment); |
1743 if (parsed.username.is_valid() || parsed.password.is_valid()) { | 1749 if (parsed.username.is_valid() || parsed.password.is_valid()) |
1744 size_t at_sign = (parsed.password.is_valid() ? | |
1745 parsed.password : parsed.username).end(); | |
1746 DCHECK_EQ(static_cast<size_t>(parsed.host.begin - 1), at_sign); | |
1747 std::vector<size_t>::const_iterator at_sign_iter = | |
1748 std::find(original_offsets.begin(), original_offsets.end(), at_sign); | |
1749 if (at_sign_iter != original_offsets.end()) { | |
1750 (*offsets_for_adjustment)[at_sign_iter - original_offsets.begin()] = | |
1751 url_string.length(); | |
1752 } | |
1753 url_string.push_back('@'); | 1750 url_string.push_back('@'); |
1754 } | |
1755 } | 1751 } |
1756 if (prefix_end) | 1752 if (prefix_end) |
1757 *prefix_end = static_cast<size_t>(url_string.length()); | 1753 *prefix_end = static_cast<size_t>(url_string.length()); |
1758 | 1754 |
1759 // Host. | 1755 // Host. |
1760 AppendFormattedComponent(spec, parsed.host, original_offsets, | 1756 AppendFormattedComponent(spec, parsed.host, original_offsets, |
1761 HostComponentTransform(languages), &url_string, &new_parsed->host, | 1757 HostComponentTransform(languages), &url_string, &new_parsed->host, |
1762 offsets_for_adjustment); | 1758 offsets_for_adjustment); |
1763 | 1759 |
1764 // Port. | 1760 // Port. |
1765 if (parsed.port.is_nonempty()) { | 1761 if (parsed.port.is_nonempty()) { |
1766 url_string.push_back(':'); | 1762 url_string.push_back(':'); |
1767 new_parsed->port.begin = url_string.length(); | 1763 new_parsed->port.begin = url_string.length(); |
1768 url_string.insert(url_string.end(), | 1764 url_string.insert(url_string.end(), |
1769 spec.begin() + parsed.port.begin, | 1765 spec.begin() + parsed.port.begin, |
1770 spec.begin() + parsed.port.end()); | 1766 spec.begin() + parsed.port.end()); |
1771 new_parsed->port.len = url_string.length() - new_parsed->port.begin; | 1767 new_parsed->port.len = url_string.length() - new_parsed->port.begin; |
1772 } else { | 1768 } else { |
1773 new_parsed->port.reset(); | 1769 new_parsed->port.reset(); |
1774 } | 1770 } |
1775 | 1771 |
1776 // Path & query. Both get the same general unescape & convert treatment. | 1772 // Path & query. Both get the same general unescape & convert treatment. |
1777 if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || | 1773 if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || |
1778 !CanStripTrailingSlash(url)) { | 1774 !CanStripTrailingSlash(url)) { |
1779 AppendFormattedComponent(spec, parsed.path, original_offsets, | 1775 AppendFormattedComponent(spec, parsed.path, original_offsets, |
1780 NonHostComponentTransform(unescape_rules), &url_string, | 1776 NonHostComponentTransform(unescape_rules), &url_string, |
1781 &new_parsed->path, offsets_for_adjustment); | 1777 &new_parsed->path, offsets_for_adjustment); |
| 1778 } else { |
| 1779 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); |
| 1780 offset_adjuster.Add(base::OffsetAdjuster::Adjustment( |
| 1781 url_string.length(), parsed.path.len, 0)); |
1782 } | 1782 } |
1783 if (parsed.query.is_valid()) | 1783 if (parsed.query.is_valid()) |
1784 url_string.push_back('?'); | 1784 url_string.push_back('?'); |
1785 AppendFormattedComponent(spec, parsed.query, original_offsets, | 1785 AppendFormattedComponent(spec, parsed.query, original_offsets, |
1786 NonHostComponentTransform(unescape_rules), &url_string, | 1786 NonHostComponentTransform(unescape_rules), &url_string, |
1787 &new_parsed->query, offsets_for_adjustment); | 1787 &new_parsed->query, offsets_for_adjustment); |
1788 | 1788 |
1789 // Ref. This is valid, unescaped UTF-8, so we can just convert. | 1789 // Ref. This is valid, unescaped UTF-8, so we can just convert. |
1790 if (parsed.ref.is_valid()) { | 1790 if (parsed.ref.is_valid()) |
1791 url_string.push_back('#'); | 1791 url_string.push_back('#'); |
1792 size_t original_ref_begin = static_cast<size_t>(parsed.ref.begin); | 1792 AppendFormattedComponent(spec, parsed.ref, original_offsets, |
1793 size_t output_ref_begin = url_string.length(); | 1793 NonHostComponentTransform(UnescapeRule::NONE), &url_string, |
1794 new_parsed->ref.begin = static_cast<int>(output_ref_begin); | 1794 &new_parsed->ref, offsets_for_adjustment); |
1795 | |
1796 std::vector<size_t> offsets_into_ref( | |
1797 OffsetsIntoComponent(original_offsets, original_ref_begin)); | |
1798 if (parsed.ref.len > 0) { | |
1799 url_string.append(base::UTF8ToUTF16AndAdjustOffsets( | |
1800 spec.substr(original_ref_begin, static_cast<size_t>(parsed.ref.len)), | |
1801 &offsets_into_ref)); | |
1802 } | |
1803 | |
1804 new_parsed->ref.len = | |
1805 static_cast<int>(url_string.length() - new_parsed->ref.begin); | |
1806 AdjustForComponentTransform(original_offsets, original_ref_begin, | |
1807 static_cast<size_t>(parsed.ref.end()), offsets_into_ref, | |
1808 output_ref_begin, offsets_for_adjustment); | |
1809 } | |
1810 | 1795 |
1811 // If we need to strip out http do it after the fact. This way we don't need | 1796 // If we need to strip out http do it after the fact. This way we don't need |
1812 // to worry about how offset_for_adjustment is interpreted. | 1797 // to worry about how offset_for_adjustment is interpreted. |
1813 if (omit_http && StartsWith(url_string, ASCIIToUTF16(kHTTP), true)) { | 1798 if (omit_http && StartsWith(url_string, ASCIIToUTF16(kHTTP), true)) { |
1814 const size_t kHTTPSize = arraysize(kHTTP) - 1; | 1799 const size_t kHTTPSize = arraysize(kHTTP) - 1; |
1815 url_string = url_string.substr(kHTTPSize); | 1800 url_string = url_string.substr(kHTTPSize); |
1816 if (offsets_for_adjustment && !offsets_for_adjustment->empty()) { | 1801 if (offsets_for_adjustment && !offsets_for_adjustment->empty()) { |
1817 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); | 1802 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); |
1818 offset_adjuster.Add(base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); | 1803 offset_adjuster.Add(base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); |
1819 } | 1804 } |
1820 if (prefix_end) | 1805 if (prefix_end) |
1821 *prefix_end -= kHTTPSize; | 1806 *prefix_end -= kHTTPSize; |
1822 | 1807 |
1823 // Adjust new_parsed. | 1808 // Adjust new_parsed. |
1824 DCHECK(new_parsed->scheme.is_valid()); | 1809 DCHECK(new_parsed->scheme.is_valid()); |
1825 int delta = -(new_parsed->scheme.len + 3); // +3 for ://. | 1810 int delta = -(new_parsed->scheme.len + 3); // +3 for ://. |
1826 new_parsed->scheme.reset(); | 1811 new_parsed->scheme.reset(); |
1827 AdjustComponents(delta, new_parsed); | 1812 AdjustAllComponentsButScheme(delta, new_parsed); |
1828 } | 1813 } |
1829 | 1814 |
1830 LimitOffsets(url_string, offsets_for_adjustment); | 1815 LimitOffsets(url_string, offsets_for_adjustment); |
1831 return url_string; | 1816 return url_string; |
1832 } | 1817 } |
1833 | 1818 |
1834 base::string16 FormatUrl(const GURL& url, | 1819 base::string16 FormatUrl(const GURL& url, |
1835 const std::string& languages, | 1820 const std::string& languages, |
1836 FormatUrlTypes format_types, | 1821 FormatUrlTypes format_types, |
1837 UnescapeRule::Type unescape_rules, | 1822 UnescapeRule::Type unescape_rules, |
1838 url_parse::Parsed* new_parsed, | 1823 url_parse::Parsed* new_parsed, |
1839 size_t* prefix_end, | 1824 size_t* prefix_end, |
1840 size_t* offset_for_adjustment) { | 1825 size_t* offset_for_adjustment) { |
1841 std::vector<size_t> offsets; | 1826 Offsets offsets; |
1842 if (offset_for_adjustment) | 1827 if (offset_for_adjustment) |
1843 offsets.push_back(*offset_for_adjustment); | 1828 offsets.push_back(*offset_for_adjustment); |
1844 base::string16 result = FormatUrlWithOffsets(url, languages, format_types, | 1829 base::string16 result = FormatUrlWithOffsets(url, languages, format_types, |
1845 unescape_rules, new_parsed, prefix_end, &offsets); | 1830 unescape_rules, new_parsed, prefix_end, &offsets); |
1846 if (offset_for_adjustment) | 1831 if (offset_for_adjustment) |
1847 *offset_for_adjustment = offsets[0]; | 1832 *offset_for_adjustment = offsets[0]; |
1848 return result; | 1833 return result; |
1849 } | 1834 } |
1850 | 1835 |
1851 bool CanStripTrailingSlash(const GURL& url) { | 1836 bool CanStripTrailingSlash(const GURL& url) { |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2161 | 2146 |
2162 NetworkInterface::NetworkInterface(const std::string& name, | 2147 NetworkInterface::NetworkInterface(const std::string& name, |
2163 const IPAddressNumber& address) | 2148 const IPAddressNumber& address) |
2164 : name(name), address(address) { | 2149 : name(name), address(address) { |
2165 } | 2150 } |
2166 | 2151 |
2167 NetworkInterface::~NetworkInterface() { | 2152 NetworkInterface::~NetworkInterface() { |
2168 } | 2153 } |
2169 | 2154 |
2170 } // namespace net | 2155 } // namespace net |
OLD | NEW |