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 // Converts |original_offsets| into a vector of offsets relative to a specific |
512 // offsets. Any offset which was not at least this large to begin with is set | 512 // component by subtracting |component_begin| from each element. Callers should |
513 // to std::string::npos. | 513 // then perform some transformation on that component, then translate these |
514 std::vector<size_t> OffsetsIntoComponent( | 514 // offsets back to absolute ones using AdjustForComponentTransform(). |
515 const std::vector<size_t>& original_offsets, | 515 // |
516 size_t component_begin) { | 516 // NOTE: Offsets which didn't originally point into this component may be |
msw
2013/09/09 19:15:52
nit: With this helper intact, it's less compelling
Peter Kasting
2013/09/09 23:43:02
Moot.
| |
517 DCHECK_NE(std::string::npos, component_begin); | 517 // transformed to bizarre values; this doesn't hurt anything, since |
518 std::vector<size_t> offsets_into_component(original_offsets); | 518 // AdjustForComponentTransform() should ignore these values. |
519 for (std::vector<size_t>::iterator i(offsets_into_component.begin()); | 519 Offsets OffsetsIntoComponent(const Offsets& original_offsets, |
msw
2013/09/09 19:15:52
Can this be replaced with an OffsetAdjuster?
Peter Kasting
2013/09/09 23:43:02
Done.
| |
520 i != offsets_into_component.end(); ++i) { | 520 size_t component_begin) { |
521 if (*i != std::string::npos) | 521 Offsets offsets_into_component(original_offsets); |
msw
2013/09/09 19:15:52
optional nit: rename this to |offsets| for a short
Peter Kasting
2013/09/09 23:43:02
Moot.
| |
522 *i = (*i < component_begin) ? std::string::npos : (*i - component_begin); | 522 for (Offsets::iterator i(offsets_into_component.begin()); |
523 } | 523 i != offsets_into_component.end(); ++i) |
524 *i -= component_begin; | |
524 return offsets_into_component; | 525 return offsets_into_component; |
525 } | 526 } |
526 | 527 |
527 // Called after we transform a component and append it to an output string. | 528 // Called after transforming a component to set all affected elements in |
528 // Maps |transformed_offsets|, which represent offsets into the transformed | 529 // |offsets_for_adjustment| to the correct new values. |original_offsets| |
529 // component itself, into appropriate offsets for the output string, by adding | 530 // represents the offsets before the transform; |original_component_begin| and |
530 // |output_component_begin| to each. Determines which offsets need mapping by | 531 // |original_component_end| represent the pre-transform boundaries of the |
531 // checking to see which of the |original_offsets| were within the designated | 532 // affected component. |transformed_offsets| should be a vector created by |
532 // original component, using its provided endpoints. | 533 // OffsetsIntoComponent() and then transformed along with the component. Note |
533 void AdjustForComponentTransform( | 534 // that any elements in this vector which didn't originally point into the |
534 const std::vector<size_t>& original_offsets, | 535 // component may contain arbitrary values and should be ignored. |
535 size_t original_component_begin, | 536 // |transformed_component_begin| and |transformed_component_end| are the |
536 size_t original_component_end, | 537 // endpoints of the transformed component and are used in combination with the |
537 const std::vector<size_t>& transformed_offsets, | 538 // two offset vectors to calculate the resulting absolute offsets, which are |
538 size_t output_component_begin, | 539 // stored in |offsets_for_adjustment|. |
539 std::vector<size_t>* offsets_for_adjustment) { | 540 void AdjustForComponentTransform(const Offsets& original_offsets, |
541 size_t original_component_begin, | |
msw
2013/09/09 19:15:52
optional nit: Replace 2 begin/end pairs with Range
Peter Kasting
2013/09/09 23:43:02
This turns out to not be particularly great at the
| |
542 size_t original_component_end, | |
543 const Offsets& transformed_offsets, | |
544 size_t transformed_component_begin, | |
545 size_t transformed_component_end, | |
546 Offsets* offsets_for_adjustment) { | |
540 if (!offsets_for_adjustment) | 547 if (!offsets_for_adjustment) |
541 return; | 548 return; // Nothing to do. |
542 | 549 |
543 DCHECK_NE(std::string::npos, original_component_begin); | 550 for (size_t i = 0; i < original_offsets.size(); ++i) { |
msw
2013/09/09 19:15:52
Can this be replaced with an OffsetAdjuster?
Peter Kasting
2013/09/09 23:43:02
Not really.
It's sort of possible to do with two
| |
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]; | 551 size_t original_offset = original_offsets[i]; |
551 if ((original_offset >= original_component_begin) && | 552 if ((original_offset >= original_component_begin) && |
552 (original_offset < original_component_end)) { | 553 (original_offset < original_component_end)) { |
554 // This offset originally pointed into the transformed component. | |
555 // Adjust the transformed relative offset by the new beginning point of | |
556 // the transformed component. | |
553 size_t transformed_offset = transformed_offsets[i]; | 557 size_t transformed_offset = transformed_offsets[i]; |
554 (*offsets_for_adjustment)[i] = | 558 (*offsets_for_adjustment)[i] = |
555 (transformed_offset == base::string16::npos) ? | 559 (transformed_offset == base::string16::npos) ? |
556 base::string16::npos : (output_component_begin + transformed_offset); | 560 base::string16::npos : |
561 (transformed_offset + transformed_component_begin); | |
562 } else if ((original_offset >= original_component_end) && | |
563 (original_offset != std::string::npos)) { | |
564 // This offset pointed after the transformed component. Adjust the | |
565 // original absolute offset by the difference between the new and old | |
566 // component lengths. | |
567 (*offsets_for_adjustment)[i] = | |
568 original_offset - original_component_end + transformed_component_end; | |
557 } | 569 } |
558 } | 570 } |
559 } | 571 } |
560 | 572 |
561 // If |component| is valid, its begin is incremented by |delta|. | 573 // If |component| is valid, its begin is incremented by |delta|. |
562 void AdjustComponent(int delta, url_parse::Component* component) { | 574 void AdjustComponent(int delta, url_parse::Component* component) { |
563 if (!component->is_valid()) | 575 if (!component->is_valid()) |
564 return; | 576 return; |
565 | 577 |
566 DCHECK(delta >= 0 || component->begin >= -delta); | 578 DCHECK(delta >= 0 || component->begin >= -delta); |
567 component->begin += delta; | 579 component->begin += delta; |
568 } | 580 } |
569 | 581 |
570 // Adjusts all the components of |parsed| by |delta|, except for the scheme. | 582 // Adjusts all the components of |parsed| by |delta|, except for the scheme. |
571 void AdjustComponents(int delta, url_parse::Parsed* parsed) { | 583 void AdjustAllComponentsButScheme(int delta, url_parse::Parsed* parsed) { |
572 AdjustComponent(delta, &(parsed->username)); | 584 AdjustComponent(delta, &(parsed->username)); |
573 AdjustComponent(delta, &(parsed->password)); | 585 AdjustComponent(delta, &(parsed->password)); |
574 AdjustComponent(delta, &(parsed->host)); | 586 AdjustComponent(delta, &(parsed->host)); |
575 AdjustComponent(delta, &(parsed->port)); | 587 AdjustComponent(delta, &(parsed->port)); |
576 AdjustComponent(delta, &(parsed->path)); | 588 AdjustComponent(delta, &(parsed->path)); |
577 AdjustComponent(delta, &(parsed->query)); | 589 AdjustComponent(delta, &(parsed->query)); |
578 AdjustComponent(delta, &(parsed->ref)); | 590 AdjustComponent(delta, &(parsed->ref)); |
579 } | 591 } |
580 | 592 |
581 // Helper for FormatUrlWithOffsets(). | 593 // Helper for FormatUrlWithOffsets(). |
582 base::string16 FormatViewSourceUrl( | 594 base::string16 FormatViewSourceUrl(const GURL& url, |
583 const GURL& url, | 595 const Offsets& original_offsets, |
584 const std::vector<size_t>& original_offsets, | 596 const std::string& languages, |
585 const std::string& languages, | 597 FormatUrlTypes format_types, |
586 FormatUrlTypes format_types, | 598 UnescapeRule::Type unescape_rules, |
587 UnescapeRule::Type unescape_rules, | 599 url_parse::Parsed* new_parsed, |
588 url_parse::Parsed* new_parsed, | 600 size_t* prefix_end, |
589 size_t* prefix_end, | 601 Offsets* offsets_for_adjustment) { |
590 std::vector<size_t>* offsets_for_adjustment) { | |
591 DCHECK(new_parsed); | 602 DCHECK(new_parsed); |
592 const char kViewSource[] = "view-source:"; | 603 const char kViewSource[] = "view-source:"; |
593 const size_t kViewSourceLength = arraysize(kViewSource) - 1; | 604 const size_t kViewSourceLength = arraysize(kViewSource) - 1; |
594 std::vector<size_t> offsets_into_url( | 605 |
606 // Format the underlying URL and adjust offsets. | |
607 const std::string& url_str(url.possibly_invalid_spec()); | |
608 Offsets offsets_into_underlying_url( | |
595 OffsetsIntoComponent(original_offsets, kViewSourceLength)); | 609 OffsetsIntoComponent(original_offsets, kViewSourceLength)); |
610 base::string16 result(ASCIIToUTF16(kViewSource) + | |
611 FormatUrlWithOffsets(GURL(url_str.substr(kViewSourceLength)), languages, | |
612 format_types, unescape_rules, new_parsed, prefix_end, | |
613 &offsets_into_underlying_url)); | |
614 AdjustForComponentTransform(original_offsets, kViewSourceLength, | |
615 url_str.length(), offsets_into_underlying_url, | |
616 kViewSourceLength, result.length(), | |
617 offsets_for_adjustment); | |
618 LimitOffsets(result, offsets_for_adjustment); | |
596 | 619 |
597 GURL real_url(url.possibly_invalid_spec().substr(kViewSourceLength)); | 620 // Adjust positions of the parsed components. |
598 base::string16 result(ASCIIToUTF16(kViewSource) + | |
599 FormatUrlWithOffsets(real_url, languages, format_types, unescape_rules, | |
600 new_parsed, prefix_end, &offsets_into_url)); | |
601 | |
602 // Adjust position values. | |
603 if (new_parsed->scheme.is_nonempty()) { | 621 if (new_parsed->scheme.is_nonempty()) { |
604 // Assume "view-source:real-scheme" as a scheme. | 622 // Assume "view-source:real-scheme" as a scheme. |
605 new_parsed->scheme.len += kViewSourceLength; | 623 new_parsed->scheme.len += kViewSourceLength; |
606 } else { | 624 } else { |
607 new_parsed->scheme.begin = 0; | 625 new_parsed->scheme.begin = 0; |
608 new_parsed->scheme.len = kViewSourceLength - 1; | 626 new_parsed->scheme.len = kViewSourceLength - 1; |
609 } | 627 } |
610 AdjustComponents(kViewSourceLength, new_parsed); | 628 AdjustAllComponentsButScheme(kViewSourceLength, new_parsed); |
629 | |
611 if (prefix_end) | 630 if (prefix_end) |
612 *prefix_end += kViewSourceLength; | 631 *prefix_end += kViewSourceLength; |
613 AdjustForComponentTransform(original_offsets, kViewSourceLength, | 632 |
614 url.possibly_invalid_spec().length(), offsets_into_url, kViewSourceLength, | |
615 offsets_for_adjustment); | |
616 LimitOffsets(result, offsets_for_adjustment); | |
617 return result; | 633 return result; |
618 } | 634 } |
619 | 635 |
620 class AppendComponentTransform { | 636 class AppendComponentTransform { |
621 public: | 637 public: |
622 AppendComponentTransform() {} | 638 AppendComponentTransform() {} |
623 virtual ~AppendComponentTransform() {} | 639 virtual ~AppendComponentTransform() {} |
624 | 640 |
625 virtual base::string16 Execute( | 641 virtual base::string16 Execute(const std::string& component_text, |
626 const std::string& component_text, | 642 Offsets* offsets_into_component) const = 0; |
627 std::vector<size_t>* offsets_into_component) const = 0; | |
628 | 643 |
629 // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an | 644 // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an |
630 // accessible copy constructor in order to call AppendFormattedComponent() | 645 // accessible copy constructor in order to call AppendFormattedComponent() |
631 // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ). | 646 // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ). |
632 }; | 647 }; |
633 | 648 |
634 class HostComponentTransform : public AppendComponentTransform { | 649 class HostComponentTransform : public AppendComponentTransform { |
635 public: | 650 public: |
636 explicit HostComponentTransform(const std::string& languages) | 651 explicit HostComponentTransform(const std::string& languages) |
637 : languages_(languages) { | 652 : languages_(languages) { |
638 } | 653 } |
639 | 654 |
640 private: | 655 private: |
641 virtual base::string16 Execute( | 656 virtual base::string16 Execute( |
642 const std::string& component_text, | 657 const std::string& component_text, |
643 std::vector<size_t>* offsets_into_component) const OVERRIDE { | 658 Offsets* offsets_into_component) const OVERRIDE { |
644 return IDNToUnicodeWithOffsets(component_text, languages_, | 659 return IDNToUnicodeWithOffsets(component_text, languages_, |
645 offsets_into_component); | 660 offsets_into_component); |
646 } | 661 } |
647 | 662 |
648 const std::string& languages_; | 663 const std::string& languages_; |
649 }; | 664 }; |
650 | 665 |
651 class NonHostComponentTransform : public AppendComponentTransform { | 666 class NonHostComponentTransform : public AppendComponentTransform { |
652 public: | 667 public: |
653 explicit NonHostComponentTransform(UnescapeRule::Type unescape_rules) | 668 explicit NonHostComponentTransform(UnescapeRule::Type unescape_rules) |
654 : unescape_rules_(unescape_rules) { | 669 : unescape_rules_(unescape_rules) { |
655 } | 670 } |
656 | 671 |
657 private: | 672 private: |
658 virtual base::string16 Execute( | 673 virtual base::string16 Execute( |
659 const std::string& component_text, | 674 const std::string& component_text, |
660 std::vector<size_t>* offsets_into_component) const OVERRIDE { | 675 Offsets* offsets_into_component) const OVERRIDE { |
661 return (unescape_rules_ == UnescapeRule::NONE) ? | 676 return (unescape_rules_ == UnescapeRule::NONE) ? |
662 base::UTF8ToUTF16AndAdjustOffsets(component_text, | 677 base::UTF8ToUTF16AndAdjustOffsets(component_text, |
663 offsets_into_component) : | 678 offsets_into_component) : |
664 UnescapeAndDecodeUTF8URLComponentWithOffsets(component_text, | 679 UnescapeAndDecodeUTF8URLComponentWithOffsets(component_text, |
665 unescape_rules_, offsets_into_component); | 680 unescape_rules_, offsets_into_component); |
666 } | 681 } |
667 | 682 |
668 const UnescapeRule::Type unescape_rules_; | 683 const UnescapeRule::Type unescape_rules_; |
669 }; | 684 }; |
670 | 685 |
686 // Transforms the portion of |spec| covered by |original_component| according to | |
687 // |transform|. Appends the result to |output|. If |output_component| is | |
688 // non-NULL, its start and length are set to the transformed component's new | |
689 // start and length. For each element in |original_offsets| which is at least | |
690 // as large as original_component.begin, the corresponding element of | |
691 // |offsets_for_adjustment| is transformed appropriately. | |
671 void AppendFormattedComponent(const std::string& spec, | 692 void AppendFormattedComponent(const std::string& spec, |
672 const url_parse::Component& original_component, | 693 const url_parse::Component& original_component, |
673 const std::vector<size_t>& original_offsets, | 694 const Offsets& original_offsets, |
674 const AppendComponentTransform& transform, | 695 const AppendComponentTransform& transform, |
675 base::string16* output, | 696 base::string16* output, |
676 url_parse::Component* output_component, | 697 url_parse::Component* output_component, |
677 std::vector<size_t>* offsets_for_adjustment) { | 698 Offsets* offsets_for_adjustment) { |
678 DCHECK(output); | 699 DCHECK(output); |
679 if (original_component.is_nonempty()) { | 700 if (original_component.is_nonempty()) { |
680 size_t original_component_begin = | 701 size_t original_component_begin = |
681 static_cast<size_t>(original_component.begin); | 702 static_cast<size_t>(original_component.begin); |
682 size_t output_component_begin = output->length(); | 703 size_t output_component_begin = output->length(); |
683 if (output_component) | 704 std::string component_str(spec, original_component_begin, |
705 static_cast<size_t>(original_component.len)); | |
706 | |
707 // Transform |component_str| and adjust the offsets accordingly. | |
708 Offsets offsets_into_component( | |
709 OffsetsIntoComponent(original_offsets, original_component_begin)); | |
710 output->append(transform.Execute(component_str, &offsets_into_component)); | |
711 AdjustForComponentTransform(original_offsets, original_component_begin, | |
712 static_cast<size_t>(original_component.end()), | |
713 offsets_into_component, output_component_begin, | |
714 output->length(), offsets_for_adjustment); | |
715 | |
716 // Set positions of the parsed component. | |
717 if (output_component) { | |
684 output_component->begin = static_cast<int>(output_component_begin); | 718 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 = | 719 output_component->len = |
693 static_cast<int>(output->length() - output_component_begin); | 720 static_cast<int>(output->length() - output_component_begin); |
694 } | 721 } |
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) { | 722 } else if (output_component) { |
700 output_component->reset(); | 723 output_component->reset(); |
701 } | 724 } |
702 } | 725 } |
703 | 726 |
704 void SanitizeGeneratedFileName(base::FilePath::StringType* filename, | 727 void SanitizeGeneratedFileName(base::FilePath::StringType* filename, |
705 bool replace_trailing) { | 728 bool replace_trailing) { |
706 const base::FilePath::CharType kReplace[] = FILE_PATH_LITERAL("-"); | 729 const base::FilePath::CharType kReplace[] = FILE_PATH_LITERAL("-"); |
707 if (filename->empty()) | 730 if (filename->empty()) |
708 return; | 731 return; |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1630 *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags, NULL); | 1653 *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags, NULL); |
1631 } | 1654 } |
1632 | 1655 |
1633 std::string GetHostOrSpecFromURL(const GURL& url) { | 1656 std::string GetHostOrSpecFromURL(const GURL& url) { |
1634 return url.has_host() ? TrimEndingDot(url.host()) : url.spec(); | 1657 return url.has_host() ? TrimEndingDot(url.host()) : url.spec(); |
1635 } | 1658 } |
1636 | 1659 |
1637 void AppendFormattedHost(const GURL& url, | 1660 void AppendFormattedHost(const GURL& url, |
1638 const std::string& languages, | 1661 const std::string& languages, |
1639 base::string16* output) { | 1662 base::string16* output) { |
1640 std::vector<size_t> offsets; | 1663 Offsets offsets; |
1641 AppendFormattedComponent(url.possibly_invalid_spec(), | 1664 AppendFormattedComponent(url.possibly_invalid_spec(), |
1642 url.parsed_for_possibly_invalid_spec().host, offsets, | 1665 url.parsed_for_possibly_invalid_spec().host, offsets, |
1643 HostComponentTransform(languages), output, NULL, NULL); | 1666 HostComponentTransform(languages), output, NULL, NULL); |
1644 } | 1667 } |
1645 | 1668 |
1646 base::string16 FormatUrlWithOffsets( | 1669 base::string16 FormatUrlWithOffsets( |
1647 const GURL& url, | 1670 const GURL& url, |
1648 const std::string& languages, | 1671 const std::string& languages, |
1649 FormatUrlTypes format_types, | 1672 FormatUrlTypes format_types, |
1650 UnescapeRule::Type unescape_rules, | 1673 UnescapeRule::Type unescape_rules, |
1651 url_parse::Parsed* new_parsed, | 1674 url_parse::Parsed* new_parsed, |
1652 size_t* prefix_end, | 1675 size_t* prefix_end, |
1653 std::vector<size_t>* offsets_for_adjustment) { | 1676 Offsets* offsets_for_adjustment) { |
1654 url_parse::Parsed parsed_temp; | 1677 url_parse::Parsed parsed_temp; |
1655 if (!new_parsed) | 1678 if (!new_parsed) |
1656 new_parsed = &parsed_temp; | 1679 new_parsed = &parsed_temp; |
1657 else | 1680 else |
1658 *new_parsed = url_parse::Parsed(); | 1681 *new_parsed = url_parse::Parsed(); |
1659 std::vector<size_t> original_offsets; | 1682 Offsets original_offsets; |
1660 if (offsets_for_adjustment) | 1683 if (offsets_for_adjustment) |
1661 original_offsets = *offsets_for_adjustment; | 1684 original_offsets = *offsets_for_adjustment; |
1662 | 1685 |
1663 // Special handling for view-source:. Don't use content::kViewSourceScheme | 1686 // Special handling for view-source:. Don't use content::kViewSourceScheme |
1664 // because this library shouldn't depend on chrome. | 1687 // because this library shouldn't depend on chrome. |
1665 const char* const kViewSource = "view-source"; | 1688 const char* const kViewSource = "view-source"; |
1666 // Reject "view-source:view-source:..." to avoid deep recursion. | 1689 // Reject "view-source:view-source:..." to avoid deep recursion. |
1667 const char* const kViewSourceTwice = "view-source:view-source:"; | 1690 const char* const kViewSourceTwice = "view-source:view-source:"; |
1668 if (url.SchemeIs(kViewSource) && | 1691 if (url.SchemeIs(kViewSource) && |
1669 !StartsWithASCII(url.possibly_invalid_spec(), kViewSourceTwice, false)) { | 1692 !StartsWithASCII(url.possibly_invalid_spec(), kViewSourceTwice, false)) { |
1670 return FormatViewSourceUrl(url, original_offsets, languages, format_types, | 1693 return FormatViewSourceUrl(url, original_offsets, languages, format_types, |
1671 unescape_rules, new_parsed, prefix_end, offsets_for_adjustment); | 1694 unescape_rules, new_parsed, prefix_end, |
1695 offsets_for_adjustment); | |
1672 } | 1696 } |
1673 | 1697 |
1674 // We handle both valid and invalid URLs (this will give us the spec | 1698 // We handle both valid and invalid URLs (this will give us the spec |
1675 // regardless of validity). | 1699 // regardless of validity). |
1676 const std::string& spec = url.possibly_invalid_spec(); | 1700 const std::string& spec = url.possibly_invalid_spec(); |
1677 const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); | 1701 const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); |
1678 | 1702 |
1679 // Scheme & separators. These are ASCII. | 1703 // Scheme & separators. These are ASCII. |
1680 base::string16 url_string; | 1704 base::string16 url_string; |
1681 url_string.insert(url_string.end(), spec.begin(), | 1705 url_string.insert(url_string.end(), spec.begin(), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1719 // username/password. | 1743 // username/password. |
1720 offset_adjuster.Add(base::OffsetAdjuster::Adjustment( | 1744 offset_adjuster.Add(base::OffsetAdjuster::Adjustment( |
1721 static_cast<size_t>(nonempty_component->begin), | 1745 static_cast<size_t>(nonempty_component->begin), |
1722 static_cast<size_t>(nonempty_component->len + 1), 0)); | 1746 static_cast<size_t>(nonempty_component->len + 1), 0)); |
1723 } | 1747 } |
1724 } | 1748 } |
1725 } else { | 1749 } else { |
1726 AppendFormattedComponent(spec, parsed.username, original_offsets, | 1750 AppendFormattedComponent(spec, parsed.username, original_offsets, |
1727 NonHostComponentTransform(unescape_rules), &url_string, | 1751 NonHostComponentTransform(unescape_rules), &url_string, |
1728 &new_parsed->username, offsets_for_adjustment); | 1752 &new_parsed->username, offsets_for_adjustment); |
1729 if (parsed.password.is_valid()) { | 1753 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(':'); | 1754 url_string.push_back(':'); |
1739 } | |
1740 AppendFormattedComponent(spec, parsed.password, original_offsets, | 1755 AppendFormattedComponent(spec, parsed.password, original_offsets, |
1741 NonHostComponentTransform(unescape_rules), &url_string, | 1756 NonHostComponentTransform(unescape_rules), &url_string, |
1742 &new_parsed->password, offsets_for_adjustment); | 1757 &new_parsed->password, offsets_for_adjustment); |
1743 if (parsed.username.is_valid() || parsed.password.is_valid()) { | 1758 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('@'); | 1759 url_string.push_back('@'); |
1754 } | |
1755 } | 1760 } |
1756 if (prefix_end) | 1761 if (prefix_end) |
1757 *prefix_end = static_cast<size_t>(url_string.length()); | 1762 *prefix_end = static_cast<size_t>(url_string.length()); |
1758 | 1763 |
1759 // Host. | 1764 // Host. |
1760 AppendFormattedComponent(spec, parsed.host, original_offsets, | 1765 AppendFormattedComponent(spec, parsed.host, original_offsets, |
1761 HostComponentTransform(languages), &url_string, &new_parsed->host, | 1766 HostComponentTransform(languages), &url_string, &new_parsed->host, |
1762 offsets_for_adjustment); | 1767 offsets_for_adjustment); |
1763 | 1768 |
1764 // Port. | 1769 // Port. |
1765 if (parsed.port.is_nonempty()) { | 1770 if (parsed.port.is_nonempty()) { |
1766 url_string.push_back(':'); | 1771 url_string.push_back(':'); |
1767 new_parsed->port.begin = url_string.length(); | 1772 new_parsed->port.begin = url_string.length(); |
1768 url_string.insert(url_string.end(), | 1773 url_string.insert(url_string.end(), |
1769 spec.begin() + parsed.port.begin, | 1774 spec.begin() + parsed.port.begin, |
1770 spec.begin() + parsed.port.end()); | 1775 spec.begin() + parsed.port.end()); |
1771 new_parsed->port.len = url_string.length() - new_parsed->port.begin; | 1776 new_parsed->port.len = url_string.length() - new_parsed->port.begin; |
1772 } else { | 1777 } else { |
1773 new_parsed->port.reset(); | 1778 new_parsed->port.reset(); |
1774 } | 1779 } |
1775 | 1780 |
1776 // Path & query. Both get the same general unescape & convert treatment. | 1781 // Path & query. Both get the same general unescape & convert treatment. |
1777 if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || | 1782 if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || |
1778 !CanStripTrailingSlash(url)) { | 1783 !CanStripTrailingSlash(url)) { |
1779 AppendFormattedComponent(spec, parsed.path, original_offsets, | 1784 AppendFormattedComponent(spec, parsed.path, original_offsets, |
1780 NonHostComponentTransform(unescape_rules), &url_string, | 1785 NonHostComponentTransform(unescape_rules), &url_string, |
1781 &new_parsed->path, offsets_for_adjustment); | 1786 &new_parsed->path, offsets_for_adjustment); |
1787 } else { | |
1788 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); | |
1789 offset_adjuster.Add(base::OffsetAdjuster::Adjustment( | |
1790 url_string.length(), parsed.path.len, 0)); | |
1782 } | 1791 } |
1783 if (parsed.query.is_valid()) | 1792 if (parsed.query.is_valid()) |
1784 url_string.push_back('?'); | 1793 url_string.push_back('?'); |
1785 AppendFormattedComponent(spec, parsed.query, original_offsets, | 1794 AppendFormattedComponent(spec, parsed.query, original_offsets, |
1786 NonHostComponentTransform(unescape_rules), &url_string, | 1795 NonHostComponentTransform(unescape_rules), &url_string, |
1787 &new_parsed->query, offsets_for_adjustment); | 1796 &new_parsed->query, offsets_for_adjustment); |
1788 | 1797 |
1789 // Ref. This is valid, unescaped UTF-8, so we can just convert. | 1798 // Ref. This is valid, unescaped UTF-8, so we can just convert. |
1790 if (parsed.ref.is_valid()) { | 1799 if (parsed.ref.is_valid()) |
1791 url_string.push_back('#'); | 1800 url_string.push_back('#'); |
1792 size_t original_ref_begin = static_cast<size_t>(parsed.ref.begin); | 1801 AppendFormattedComponent(spec, parsed.ref, original_offsets, |
1793 size_t output_ref_begin = url_string.length(); | 1802 NonHostComponentTransform(UnescapeRule::NONE), &url_string, |
1794 new_parsed->ref.begin = static_cast<int>(output_ref_begin); | 1803 &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 | 1804 |
1811 // If we need to strip out http do it after the fact. This way we don't need | 1805 // 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. | 1806 // to worry about how offset_for_adjustment is interpreted. |
1813 if (omit_http && StartsWith(url_string, ASCIIToUTF16(kHTTP), true)) { | 1807 if (omit_http && StartsWith(url_string, ASCIIToUTF16(kHTTP), true)) { |
1814 const size_t kHTTPSize = arraysize(kHTTP) - 1; | 1808 const size_t kHTTPSize = arraysize(kHTTP) - 1; |
1815 url_string = url_string.substr(kHTTPSize); | 1809 url_string = url_string.substr(kHTTPSize); |
1816 if (offsets_for_adjustment && !offsets_for_adjustment->empty()) { | 1810 if (offsets_for_adjustment && !offsets_for_adjustment->empty()) { |
1817 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); | 1811 base::OffsetAdjuster offset_adjuster(offsets_for_adjustment); |
1818 offset_adjuster.Add(base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); | 1812 offset_adjuster.Add(base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); |
1819 } | 1813 } |
1820 if (prefix_end) | 1814 if (prefix_end) |
1821 *prefix_end -= kHTTPSize; | 1815 *prefix_end -= kHTTPSize; |
1822 | 1816 |
1823 // Adjust new_parsed. | 1817 // Adjust new_parsed. |
1824 DCHECK(new_parsed->scheme.is_valid()); | 1818 DCHECK(new_parsed->scheme.is_valid()); |
1825 int delta = -(new_parsed->scheme.len + 3); // +3 for ://. | 1819 int delta = -(new_parsed->scheme.len + 3); // +3 for ://. |
1826 new_parsed->scheme.reset(); | 1820 new_parsed->scheme.reset(); |
1827 AdjustComponents(delta, new_parsed); | 1821 AdjustAllComponentsButScheme(delta, new_parsed); |
1828 } | 1822 } |
1829 | 1823 |
1830 LimitOffsets(url_string, offsets_for_adjustment); | 1824 LimitOffsets(url_string, offsets_for_adjustment); |
1831 return url_string; | 1825 return url_string; |
1832 } | 1826 } |
1833 | 1827 |
1834 base::string16 FormatUrl(const GURL& url, | 1828 base::string16 FormatUrl(const GURL& url, |
1835 const std::string& languages, | 1829 const std::string& languages, |
1836 FormatUrlTypes format_types, | 1830 FormatUrlTypes format_types, |
1837 UnescapeRule::Type unescape_rules, | 1831 UnescapeRule::Type unescape_rules, |
1838 url_parse::Parsed* new_parsed, | 1832 url_parse::Parsed* new_parsed, |
1839 size_t* prefix_end, | 1833 size_t* prefix_end, |
1840 size_t* offset_for_adjustment) { | 1834 size_t* offset_for_adjustment) { |
1841 std::vector<size_t> offsets; | 1835 Offsets offsets; |
1842 if (offset_for_adjustment) | 1836 if (offset_for_adjustment) |
1843 offsets.push_back(*offset_for_adjustment); | 1837 offsets.push_back(*offset_for_adjustment); |
1844 base::string16 result = FormatUrlWithOffsets(url, languages, format_types, | 1838 base::string16 result = FormatUrlWithOffsets(url, languages, format_types, |
1845 unescape_rules, new_parsed, prefix_end, &offsets); | 1839 unescape_rules, new_parsed, prefix_end, &offsets); |
1846 if (offset_for_adjustment) | 1840 if (offset_for_adjustment) |
1847 *offset_for_adjustment = offsets[0]; | 1841 *offset_for_adjustment = offsets[0]; |
1848 return result; | 1842 return result; |
1849 } | 1843 } |
1850 | 1844 |
1851 bool CanStripTrailingSlash(const GURL& url) { | 1845 bool CanStripTrailingSlash(const GURL& url) { |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2161 | 2155 |
2162 NetworkInterface::NetworkInterface(const std::string& name, | 2156 NetworkInterface::NetworkInterface(const std::string& name, |
2163 const IPAddressNumber& address) | 2157 const IPAddressNumber& address) |
2164 : name(name), address(address) { | 2158 : name(name), address(address) { |
2165 } | 2159 } |
2166 | 2160 |
2167 NetworkInterface::~NetworkInterface() { | 2161 NetworkInterface::~NetworkInterface() { |
2168 } | 2162 } |
2169 | 2163 |
2170 } // namespace net | 2164 } // namespace net |
OLD | NEW |