| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "url/url_util.h" | 5 #include "url/url_util.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/strings/string_util.h" |
| 12 #include "url/url_canon_internal.h" | 13 #include "url/url_canon_internal.h" |
| 13 #include "url/url_file.h" | 14 #include "url/url_file.h" |
| 14 #include "url/url_util_internal.h" | 15 #include "url/url_util_internal.h" |
| 15 | 16 |
| 16 namespace url { | 17 namespace url { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 // ASCII-specific tolower. The standard library's tolower is locale sensitive, | |
| 21 // so we don't want to use it here. | |
| 22 template<class Char> | |
| 23 inline Char ToLowerASCII(Char c) { | |
| 24 return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c; | |
| 25 } | |
| 26 | |
| 27 // Backend for LowerCaseEqualsASCII. | |
| 28 template<typename Iter> | |
| 29 inline bool DoLowerCaseEqualsASCII(Iter a_begin, Iter a_end, const char* b) { | |
| 30 for (Iter it = a_begin; it != a_end; ++it, ++b) { | |
| 31 if (!*b || ToLowerASCII(*it) != *b) | |
| 32 return false; | |
| 33 } | |
| 34 return *b == 0; | |
| 35 } | |
| 36 | |
| 37 const int kNumStandardURLSchemes = 8; | 21 const int kNumStandardURLSchemes = 8; |
| 38 const char* kStandardURLSchemes[kNumStandardURLSchemes] = { | 22 const char* kStandardURLSchemes[kNumStandardURLSchemes] = { |
| 39 kHttpScheme, | 23 kHttpScheme, |
| 40 kHttpsScheme, | 24 kHttpsScheme, |
| 41 kFileScheme, // Yes, file urls can have a hostname! | 25 kFileScheme, // Yes, file urls can have a hostname! |
| 42 kFtpScheme, | 26 kFtpScheme, |
| 43 kGopherScheme, | 27 kGopherScheme, |
| 44 kWsScheme, // WebSocket. | 28 kWsScheme, // WebSocket. |
| 45 kWssScheme, // WebSocket secure. | 29 kWssScheme, // WebSocket secure. |
| 46 kFileSystemScheme, | 30 kFileSystemScheme, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 65 } | 49 } |
| 66 | 50 |
| 67 // Given a string and a range inside the string, compares it to the given | 51 // Given a string and a range inside the string, compares it to the given |
| 68 // lower-case |compare_to| buffer. | 52 // lower-case |compare_to| buffer. |
| 69 template<typename CHAR> | 53 template<typename CHAR> |
| 70 inline bool DoCompareSchemeComponent(const CHAR* spec, | 54 inline bool DoCompareSchemeComponent(const CHAR* spec, |
| 71 const Component& component, | 55 const Component& component, |
| 72 const char* compare_to) { | 56 const char* compare_to) { |
| 73 if (!component.is_nonempty()) | 57 if (!component.is_nonempty()) |
| 74 return compare_to[0] == 0; // When component is empty, match empty scheme. | 58 return compare_to[0] == 0; // When component is empty, match empty scheme. |
| 75 return LowerCaseEqualsASCII(&spec[component.begin], | 59 return base::LowerCaseEqualsASCII(&spec[component.begin], |
| 76 &spec[component.end()], | 60 &spec[component.end()], |
| 77 compare_to); | 61 compare_to); |
| 78 } | 62 } |
| 79 | 63 |
| 80 // Returns true if the given scheme identified by |scheme| within |spec| is one | 64 // Returns true if the given scheme identified by |scheme| within |spec| is one |
| 81 // of the registered "standard" schemes. | 65 // of the registered "standard" schemes. |
| 82 template<typename CHAR> | 66 template<typename CHAR> |
| 83 bool DoIsStandard(const CHAR* spec, const Component& scheme) { | 67 bool DoIsStandard(const CHAR* spec, const Component& scheme) { |
| 84 if (!scheme.is_nonempty()) | 68 if (!scheme.is_nonempty()) |
| 85 return false; // Empty or invalid schemes are non-standard. | 69 return false; // Empty or invalid schemes are non-standard. |
| 86 | 70 |
| 87 InitStandardSchemes(); | 71 InitStandardSchemes(); |
| 88 for (size_t i = 0; i < standard_schemes->size(); i++) { | 72 for (size_t i = 0; i < standard_schemes->size(); i++) { |
| 89 if (LowerCaseEqualsASCII(&spec[scheme.begin], &spec[scheme.end()], | 73 if (base::LowerCaseEqualsASCII(&spec[scheme.begin], &spec[scheme.end()], |
| 90 standard_schemes->at(i))) | 74 standard_schemes->at(i))) |
| 91 return true; | 75 return true; |
| 92 } | 76 } |
| 93 return false; | 77 return false; |
| 94 } | 78 } |
| 95 | 79 |
| 96 template<typename CHAR> | 80 template<typename CHAR> |
| 97 bool DoFindAndCompareScheme(const CHAR* str, | 81 bool DoFindAndCompareScheme(const CHAR* str, |
| 98 int str_len, | 82 int str_len, |
| 99 const char* compare, | 83 const char* compare, |
| 100 Component* found_scheme) { | 84 Component* found_scheme) { |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 int spec_len, | 463 int spec_len, |
| 480 const Parsed& parsed, | 464 const Parsed& parsed, |
| 481 const Replacements<base::char16>& replacements, | 465 const Replacements<base::char16>& replacements, |
| 482 CharsetConverter* charset_converter, | 466 CharsetConverter* charset_converter, |
| 483 CanonOutput* output, | 467 CanonOutput* output, |
| 484 Parsed* out_parsed) { | 468 Parsed* out_parsed) { |
| 485 return DoReplaceComponents(spec, spec_len, parsed, replacements, | 469 return DoReplaceComponents(spec, spec_len, parsed, replacements, |
| 486 charset_converter, output, out_parsed); | 470 charset_converter, output, out_parsed); |
| 487 } | 471 } |
| 488 | 472 |
| 489 // Front-ends for LowerCaseEqualsASCII. | |
| 490 bool LowerCaseEqualsASCII(const char* a_begin, | |
| 491 const char* a_end, | |
| 492 const char* b) { | |
| 493 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | |
| 494 } | |
| 495 | |
| 496 bool LowerCaseEqualsASCII(const char* a_begin, | |
| 497 const char* a_end, | |
| 498 const char* b_begin, | |
| 499 const char* b_end) { | |
| 500 while (a_begin != a_end && b_begin != b_end && | |
| 501 ToLowerASCII(*a_begin) == *b_begin) { | |
| 502 a_begin++; | |
| 503 b_begin++; | |
| 504 } | |
| 505 return a_begin == a_end && b_begin == b_end; | |
| 506 } | |
| 507 | |
| 508 bool LowerCaseEqualsASCII(const base::char16* a_begin, | |
| 509 const base::char16* a_end, | |
| 510 const char* b) { | |
| 511 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | |
| 512 } | |
| 513 | |
| 514 void DecodeURLEscapeSequences(const char* input, | 473 void DecodeURLEscapeSequences(const char* input, |
| 515 int length, | 474 int length, |
| 516 CanonOutputW* output) { | 475 CanonOutputW* output) { |
| 517 RawCanonOutputT<char> unescaped_chars; | 476 RawCanonOutputT<char> unescaped_chars; |
| 518 for (int i = 0; i < length; i++) { | 477 for (int i = 0; i < length; i++) { |
| 519 if (input[i] == '%') { | 478 if (input[i] == '%') { |
| 520 unsigned char ch; | 479 unsigned char ch; |
| 521 if (DecodeEscaped(input, &i, length, &ch)) { | 480 if (DecodeEscaped(input, &i, length, &ch)) { |
| 522 unescaped_chars.push_back(ch); | 481 unescaped_chars.push_back(ch); |
| 523 } else { | 482 } else { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 return DoCompareSchemeComponent(spec, component, compare_to); | 536 return DoCompareSchemeComponent(spec, component, compare_to); |
| 578 } | 537 } |
| 579 | 538 |
| 580 bool CompareSchemeComponent(const base::char16* spec, | 539 bool CompareSchemeComponent(const base::char16* spec, |
| 581 const Component& component, | 540 const Component& component, |
| 582 const char* compare_to) { | 541 const char* compare_to) { |
| 583 return DoCompareSchemeComponent(spec, component, compare_to); | 542 return DoCompareSchemeComponent(spec, component, compare_to); |
| 584 } | 543 } |
| 585 | 544 |
| 586 } // namespace url | 545 } // namespace url |
| OLD | NEW |