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> | |
330 void DoHost(const CHAR* spec, | 312 void DoHost(const CHAR* spec, |
331 const Component& host, | 313 const Component& host, |
332 CanonOutput* output, | 314 CanonOutput* output, |
333 CanonHostInfo* host_info) { | 315 CanonHostInfo* host_info) { |
334 if (host.len <= 0) { | 316 if (host.len <= 0) { |
335 // Empty hosts don't need anything. | 317 // Empty hosts don't need anything. |
336 host_info->family = CanonHostInfo::NEUTRAL; | 318 host_info->family = CanonHostInfo::NEUTRAL; |
337 host_info->out_host = Component(); | 319 host_info->out_host = Component(); |
338 return; | 320 return; |
339 } | 321 } |
340 | 322 |
| 323 bool has_non_ascii, has_escaped; |
| 324 ScanHostname<CHAR, UCHAR>(spec, host, &has_non_ascii, &has_escaped); |
| 325 |
341 // Keep track of output's initial length, so we can rewind later. | 326 // Keep track of output's initial length, so we can rewind later. |
342 const int output_begin = output->length(); | 327 const int output_begin = output->length(); |
343 | 328 |
344 if (DoHostSubstring<CHAR, UCHAR>(spec, host, output)) { | 329 bool success; |
| 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 { |
345 // After all the other canonicalization, check if we ended up with an IP | 343 // After all the other canonicalization, check if we ended up with an IP |
346 // address. IP addresses are small, so writing into this temporary buffer | 344 // address. IP addresses are small, so writing into this temporary buffer |
347 // should not cause an allocation. | 345 // should not cause an allocation. |
348 RawCanonOutput<64> canon_ip; | 346 RawCanonOutput<64> canon_ip; |
349 CanonicalizeIPAddress(output->data(), | 347 CanonicalizeIPAddress(output->data(), |
350 MakeRange(output_begin, output->length()), | 348 MakeRange(output_begin, output->length()), |
351 &canon_ip, host_info); | 349 &canon_ip, host_info); |
352 | 350 |
353 // If we got an IPv4/IPv6 address, copy the canonical form back to the | 351 // If we got an IPv4/IPv6 address, copy the canonical form back to the |
354 // real buffer. Otherwise, it's a hostname or broken IP, in which case | 352 // real buffer. Otherwise, it's a hostname or broken IP, in which case |
355 // we just leave it in place. | 353 // we just leave it in place. |
356 if (host_info->IsIPAddress()) { | 354 if (host_info->IsIPAddress()) { |
357 output->set_length(output_begin); | 355 output->set_length(output_begin); |
358 output->Append(canon_ip.data(), canon_ip.length()); | 356 output->Append(canon_ip.data(), canon_ip.length()); |
359 } | 357 } |
360 } else { | |
361 // Canonicalization failed. Set BROKEN to notify the caller. | |
362 host_info->family = CanonHostInfo::BROKEN; | |
363 } | 358 } |
364 | 359 |
365 host_info->out_host = MakeRange(output_begin, output->length()); | 360 host_info->out_host = MakeRange(output_begin, output->length()); |
366 } | 361 } |
367 | 362 |
368 } // namespace | 363 } // namespace |
369 | 364 |
370 bool CanonicalizeHost(const char* spec, | 365 bool CanonicalizeHost(const char* spec, |
371 const Component& host, | 366 const Component& host, |
372 CanonOutput* output, | 367 CanonOutput* output, |
(...skipping 21 matching lines...) Expand all Loading... |
394 DoHost<char, unsigned char>(spec, host, output, host_info); | 389 DoHost<char, unsigned char>(spec, host, output, host_info); |
395 } | 390 } |
396 | 391 |
397 void CanonicalizeHostVerbose(const base::char16* spec, | 392 void CanonicalizeHostVerbose(const base::char16* spec, |
398 const Component& host, | 393 const Component& host, |
399 CanonOutput* output, | 394 CanonOutput* output, |
400 CanonHostInfo* host_info) { | 395 CanonHostInfo* host_info) { |
401 DoHost<base::char16, base::char16>(spec, host, output, host_info); | 396 DoHost<base::char16, base::char16>(spec, host, output, host_info); |
402 } | 397 } |
403 | 398 |
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 | |
416 } // namespace url | 399 } // namespace url |
OLD | NEW |