| 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 |