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 <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 162 } |
163 | 163 |
164 template <typename CHAR> | 164 template <typename CHAR> |
165 bool DoCanonicalize(const CHAR* spec, | 165 bool DoCanonicalize(const CHAR* spec, |
166 int spec_len, | 166 int spec_len, |
167 bool trim_path_end, | 167 bool trim_path_end, |
168 WhitespaceRemovalPolicy whitespace_policy, | 168 WhitespaceRemovalPolicy whitespace_policy, |
169 CharsetConverter* charset_converter, | 169 CharsetConverter* charset_converter, |
170 CanonOutput* output, | 170 CanonOutput* output, |
171 Parsed* output_parsed) { | 171 Parsed* output_parsed) { |
| 172 // Reserve enough room in the output for the input, plus some extra so that |
| 173 // we have room if we have to escape a few things without reallocating. |
| 174 output->ReserveSizeIfNeeded(spec_len + 8); |
| 175 |
172 // Remove any whitespace from the middle of the relative URL if necessary. | 176 // Remove any whitespace from the middle of the relative URL if necessary. |
173 // Possibly this will result in copying to the new buffer. | 177 // Possibly this will result in copying to the new buffer. |
174 RawCanonOutputT<CHAR> whitespace_buffer; | 178 RawCanonOutputT<CHAR> whitespace_buffer; |
175 if (whitespace_policy == REMOVE_WHITESPACE) | 179 if (whitespace_policy == REMOVE_WHITESPACE) |
176 spec = RemoveURLWhitespace(spec, spec_len, &whitespace_buffer, &spec_len); | 180 spec = RemoveURLWhitespace(spec, spec_len, &whitespace_buffer, &spec_len); |
177 | 181 |
178 Parsed parsed_input; | 182 Parsed parsed_input; |
179 #ifdef WIN32 | 183 #ifdef WIN32 |
180 // For Windows, we allow things that look like absolute Windows paths to be | 184 // For Windows, we allow things that look like absolute Windows paths to be |
181 // fixed up magically to file URLs. This is done for IE compatibility. For | 185 // fixed up magically to file URLs. This is done for IE compatibility. For |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 275 |
272 bool is_relative; | 276 bool is_relative; |
273 Component relative_component; | 277 Component relative_component; |
274 if (!IsRelativeURL(base_spec, base_parsed, relative, relative_length, | 278 if (!IsRelativeURL(base_spec, base_parsed, relative, relative_length, |
275 (base_is_hierarchical || standard_base_scheme), | 279 (base_is_hierarchical || standard_base_scheme), |
276 &is_relative, &relative_component)) { | 280 &is_relative, &relative_component)) { |
277 // Error resolving. | 281 // Error resolving. |
278 return false; | 282 return false; |
279 } | 283 } |
280 | 284 |
| 285 // Don't reserve buffer space here. Instead, reserve in DoCanonicalize and |
| 286 // ReserveRelativeURL, to enable more accurate buffer sizes. |
| 287 |
281 // Pretend for a moment that |base_spec| is a standard URL. Normally | 288 // Pretend for a moment that |base_spec| is a standard URL. Normally |
282 // non-standard URLs are treated as PathURLs, but if the base has an | 289 // non-standard URLs are treated as PathURLs, but if the base has an |
283 // authority we would like to preserve it. | 290 // authority we would like to preserve it. |
284 if (is_relative && base_is_authority_based && !standard_base_scheme) { | 291 if (is_relative && base_is_authority_based && !standard_base_scheme) { |
285 Parsed base_parsed_authority; | 292 Parsed base_parsed_authority; |
286 ParseStandardURL(base_spec, base_spec_len, &base_parsed_authority); | 293 ParseStandardURL(base_spec, base_spec_len, &base_parsed_authority); |
287 if (base_parsed_authority.host.is_nonempty()) { | 294 if (base_parsed_authority.host.is_nonempty()) { |
288 RawCanonOutputT<char> temporary_output; | 295 RawCanonOutputT<char> temporary_output; |
289 bool did_resolve_succeed = | 296 bool did_resolve_succeed = |
290 ResolveRelativeURL(base_spec, base_parsed_authority, false, relative, | 297 ResolveRelativeURL(base_spec, base_parsed_authority, false, relative, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 // after this call to check validity (this assumes replacing the scheme is | 380 // after this call to check validity (this assumes replacing the scheme is |
374 // much much less common than other types of replacements, like clearing the | 381 // much much less common than other types of replacements, like clearing the |
375 // ref). | 382 // ref). |
376 Replacements<CHAR> replacements_no_scheme = replacements; | 383 Replacements<CHAR> replacements_no_scheme = replacements; |
377 replacements_no_scheme.SetScheme(NULL, Component()); | 384 replacements_no_scheme.SetScheme(NULL, Component()); |
378 return DoReplaceComponents(recanonicalized.data(), recanonicalized.length(), | 385 return DoReplaceComponents(recanonicalized.data(), recanonicalized.length(), |
379 recanonicalized_parsed, replacements_no_scheme, | 386 recanonicalized_parsed, replacements_no_scheme, |
380 charset_converter, output, out_parsed); | 387 charset_converter, output, out_parsed); |
381 } | 388 } |
382 | 389 |
| 390 // TODO(csharrison): We could be smarter about size to reserve if this is done |
| 391 // in callers below, and the code checks to see which components are being |
| 392 // replaced, and with what length. If this ends up being a hot spot it should |
| 393 // be changed. |
| 394 output->ReserveSizeIfNeeded(spec_len + 8); |
| 395 |
383 // If we get here, then we know the scheme doesn't need to be replaced, so can | 396 // If we get here, then we know the scheme doesn't need to be replaced, so can |
384 // just key off the scheme in the spec to know how to do the replacements. | 397 // just key off the scheme in the spec to know how to do the replacements. |
385 if (DoCompareSchemeComponent(spec, parsed.scheme, url::kFileScheme)) { | 398 if (DoCompareSchemeComponent(spec, parsed.scheme, url::kFileScheme)) { |
386 return ReplaceFileURL(spec, parsed, replacements, charset_converter, output, | 399 return ReplaceFileURL(spec, parsed, replacements, charset_converter, output, |
387 out_parsed); | 400 out_parsed); |
388 } | 401 } |
389 if (DoCompareSchemeComponent(spec, parsed.scheme, url::kFileSystemScheme)) { | 402 if (DoCompareSchemeComponent(spec, parsed.scheme, url::kFileSystemScheme)) { |
390 return ReplaceFileSystemURL(spec, parsed, replacements, charset_converter, | 403 return ReplaceFileSystemURL(spec, parsed, replacements, charset_converter, |
391 output, out_parsed); | 404 output, out_parsed); |
392 } | 405 } |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 return DoCompareSchemeComponent(spec, component, compare_to); | 693 return DoCompareSchemeComponent(spec, component, compare_to); |
681 } | 694 } |
682 | 695 |
683 bool CompareSchemeComponent(const base::char16* spec, | 696 bool CompareSchemeComponent(const base::char16* spec, |
684 const Component& component, | 697 const Component& component, |
685 const char* compare_to) { | 698 const char* compare_to) { |
686 return DoCompareSchemeComponent(spec, component, compare_to); | 699 return DoCompareSchemeComponent(spec, component, compare_to); |
687 } | 700 } |
688 | 701 |
689 } // namespace url | 702 } // namespace url |
OLD | NEW |