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 |