| 12432 | } |
| 12433 | |
| 12434 | ada_really_inline bool url::parse_host(std::string_view input) { |
| 12435 | ada_log("parse_host ", input, " [", input.size(), " bytes]"); |
| 12436 | if (input.empty()) { |
| 12437 | return is_valid = false; |
| 12438 | } // technically unnecessary. |
| 12439 | // If input starts with U+005B ([), then: |
| 12440 | if (input[0] == '[') { |
| 12441 | // If input does not end with U+005D (]), validation error, return failure. |
| 12442 | if (input.back() != ']') { |
| 12443 | return is_valid = false; |
| 12444 | } |
| 12445 | ada_log("parse_host ipv6"); |
| 12446 | |
| 12447 | // Return the result of IPv6 parsing input with its leading U+005B ([) and |
| 12448 | // trailing U+005D (]) removed. |
| 12449 | input.remove_prefix(1); |
| 12450 | input.remove_suffix(1); |
| 12451 | return parse_ipv6(input); |
| 12452 | } |
| 12453 | |
| 12454 | // If isNotSpecial is true, then return the result of opaque-host parsing |
| 12455 | // input. |
| 12456 | if (!is_special()) { |
| 12457 | return parse_opaque_host(input); |
| 12458 | } |
| 12459 | // Let domain be the result of running UTF-8 decode without BOM on the |
| 12460 | // percent-decoding of input. Let asciiDomain be the result of running domain |
| 12461 | // to ASCII with domain and false. The most common case is an ASCII input, in |
| 12462 | // which case we do not need to call the expensive 'to_ascii' if a few |
| 12463 | // conditions are met: no '%' and no 'xn-' subsequence. |
| 12464 | std::string buffer = std::string(input); |
| 12465 | // This next function checks that the result is ascii, but we are going to |
| 12466 | // to check anyhow with is_forbidden. |
| 12467 | // bool is_ascii = |
| 12468 | unicode::to_lower_ascii(buffer.data(), buffer.size()); |
| 12469 | bool is_forbidden = unicode::contains_forbidden_domain_code_point( |
| 12470 | buffer.data(), buffer.size()); |
| 12471 | if (is_forbidden == 0 && buffer.find("xn-") == std::string_view::npos) { |
| 12472 | // fast path |
| 12473 | host = std::move(buffer); |
| 12474 | if (checkers::is_ipv4(host.value())) { |
| 12475 | ada_log("parse_host fast path ipv4"); |
| 12476 | return parse_ipv4(host.value()); |
| 12477 | } |
| 12478 | ada_log("parse_host fast path ", *host); |
| 12479 | return true; |
| 12480 | } |
| 12481 | ada_log("parse_host calling to_ascii"); |
| 12482 | is_valid = ada::unicode::to_ascii(host, input, input.find('%')); |
| 12483 | if (!is_valid) { |
| 12484 | ada_log("parse_host to_ascii returns false"); |
| 12485 | return is_valid = false; |
| 12486 | } |
| 12487 | ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(), |
| 12488 | " bytes]"); |
| 12489 | |
| 12490 | if (std::any_of(host.value().begin(), host.value().end(), |
| 12491 | ada::unicode::is_forbidden_domain_code_point)) { |
no test coverage detected