| 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 "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "url/url_canon.h" | 6 #include "url/url_canon.h" |
| 7 #include "url/url_canon_internal.h" | 7 #include "url/url_canon_internal.h" |
| 8 | 8 |
| 9 namespace url { | 9 namespace url { |
| 10 | 10 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 has_escaped, output); | 301 has_escaped, output); |
| 302 } | 302 } |
| 303 | 303 |
| 304 // No unescaping necessary, we can safely pass the input to ICU. This | 304 // No unescaping necessary, we can safely pass the input to ICU. This |
| 305 // function will only get called if we either have escaped or non-ascii | 305 // function will only get called if we either have escaped or non-ascii |
| 306 // input, so it's safe to just use ICU now. Even if the input is ASCII, | 306 // input, so it's safe to just use ICU now. Even if the input is ASCII, |
| 307 // this function will do the right thing (just slower than we could). | 307 // this function will do the right thing (just slower than we could). |
| 308 return DoIDNHost(host, host_len, output); | 308 return DoIDNHost(host, host_len, output); |
| 309 } | 309 } |
| 310 | 310 |
| 311 template<typename CHAR, typename UCHAR> | 311 template <typename CHAR, typename UCHAR> |
| 312 bool DoHostSubstring(const CHAR* spec, |
| 313 const Component& host, |
| 314 CanonOutput* output) { |
| 315 bool has_non_ascii, has_escaped; |
| 316 ScanHostname<CHAR, UCHAR>(spec, host, &has_non_ascii, &has_escaped); |
| 317 |
| 318 if (has_non_ascii || has_escaped) { |
| 319 return DoComplexHost(&spec[host.begin], host.len, has_non_ascii, |
| 320 has_escaped, output); |
| 321 } |
| 322 |
| 323 const bool success = |
| 324 DoSimpleHost(&spec[host.begin], host.len, output, &has_non_ascii); |
| 325 DCHECK(!has_non_ascii); |
| 326 return success; |
| 327 } |
| 328 |
| 329 template <typename CHAR, typename UCHAR> |
| 312 void DoHost(const CHAR* spec, | 330 void DoHost(const CHAR* spec, |
| 313 const Component& host, | 331 const Component& host, |
| 314 CanonOutput* output, | 332 CanonOutput* output, |
| 315 CanonHostInfo* host_info) { | 333 CanonHostInfo* host_info) { |
| 316 if (host.len <= 0) { | 334 if (host.len <= 0) { |
| 317 // Empty hosts don't need anything. | 335 // Empty hosts don't need anything. |
| 318 host_info->family = CanonHostInfo::NEUTRAL; | 336 host_info->family = CanonHostInfo::NEUTRAL; |
| 319 host_info->out_host = Component(); | 337 host_info->out_host = Component(); |
| 320 return; | 338 return; |
| 321 } | 339 } |
| 322 | 340 |
| 323 bool has_non_ascii, has_escaped; | |
| 324 ScanHostname<CHAR, UCHAR>(spec, host, &has_non_ascii, &has_escaped); | |
| 325 | |
| 326 // Keep track of output's initial length, so we can rewind later. | 341 // Keep track of output's initial length, so we can rewind later. |
| 327 const int output_begin = output->length(); | 342 const int output_begin = output->length(); |
| 328 | 343 |
| 329 bool success; | 344 if (DoHostSubstring<CHAR, UCHAR>(spec, host, output)) { |
| 330 if (!has_non_ascii && !has_escaped) { | |
| 331 success = DoSimpleHost(&spec[host.begin], host.len, | |
| 332 output, &has_non_ascii); | |
| 333 DCHECK(!has_non_ascii); | |
| 334 } else { | |
| 335 success = DoComplexHost(&spec[host.begin], host.len, | |
| 336 has_non_ascii, has_escaped, output); | |
| 337 } | |
| 338 | |
| 339 if (!success) { | |
| 340 // Canonicalization failed. Set BROKEN to notify the caller. | |
| 341 host_info->family = CanonHostInfo::BROKEN; | |
| 342 } else { | |
| 343 // After all the other canonicalization, check if we ended up with an IP | 345 // After all the other canonicalization, check if we ended up with an IP |
| 344 // address. IP addresses are small, so writing into this temporary buffer | 346 // address. IP addresses are small, so writing into this temporary buffer |
| 345 // should not cause an allocation. | 347 // should not cause an allocation. |
| 346 RawCanonOutput<64> canon_ip; | 348 RawCanonOutput<64> canon_ip; |
| 347 CanonicalizeIPAddress(output->data(), | 349 CanonicalizeIPAddress(output->data(), |
| 348 MakeRange(output_begin, output->length()), | 350 MakeRange(output_begin, output->length()), |
| 349 &canon_ip, host_info); | 351 &canon_ip, host_info); |
| 350 | 352 |
| 351 // If we got an IPv4/IPv6 address, copy the canonical form back to the | 353 // If we got an IPv4/IPv6 address, copy the canonical form back to the |
| 352 // real buffer. Otherwise, it's a hostname or broken IP, in which case | 354 // real buffer. Otherwise, it's a hostname or broken IP, in which case |
| 353 // we just leave it in place. | 355 // we just leave it in place. |
| 354 if (host_info->IsIPAddress()) { | 356 if (host_info->IsIPAddress()) { |
| 355 output->set_length(output_begin); | 357 output->set_length(output_begin); |
| 356 output->Append(canon_ip.data(), canon_ip.length()); | 358 output->Append(canon_ip.data(), canon_ip.length()); |
| 357 } | 359 } |
| 360 } else { |
| 361 // Canonicalization failed. Set BROKEN to notify the caller. |
| 362 host_info->family = CanonHostInfo::BROKEN; |
| 358 } | 363 } |
| 359 | 364 |
| 360 host_info->out_host = MakeRange(output_begin, output->length()); | 365 host_info->out_host = MakeRange(output_begin, output->length()); |
| 361 } | 366 } |
| 362 | 367 |
| 363 } // namespace | 368 } // namespace |
| 364 | 369 |
| 365 bool CanonicalizeHost(const char* spec, | 370 bool CanonicalizeHost(const char* spec, |
| 366 const Component& host, | 371 const Component& host, |
| 367 CanonOutput* output, | 372 CanonOutput* output, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 389 DoHost<char, unsigned char>(spec, host, output, host_info); | 394 DoHost<char, unsigned char>(spec, host, output, host_info); |
| 390 } | 395 } |
| 391 | 396 |
| 392 void CanonicalizeHostVerbose(const base::char16* spec, | 397 void CanonicalizeHostVerbose(const base::char16* spec, |
| 393 const Component& host, | 398 const Component& host, |
| 394 CanonOutput* output, | 399 CanonOutput* output, |
| 395 CanonHostInfo* host_info) { | 400 CanonHostInfo* host_info) { |
| 396 DoHost<base::char16, base::char16>(spec, host, output, host_info); | 401 DoHost<base::char16, base::char16>(spec, host, output, host_info); |
| 397 } | 402 } |
| 398 | 403 |
| 404 bool CanonicalizeHostSubstring(const char* spec, |
| 405 const Component& host, |
| 406 CanonOutput* output) { |
| 407 return DoHostSubstring<char, unsigned char>(spec, host, output); |
| 408 } |
| 409 |
| 410 bool CanonicalizeHostSubstring(const base::char16* spec, |
| 411 const Component& host, |
| 412 CanonOutput* output) { |
| 413 return DoHostSubstring<base::char16, base::char16>(spec, host, output); |
| 414 } |
| 415 |
| 399 } // namespace url | 416 } // namespace url |
| OLD | NEW |