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 |