We return "" on error.
| 9599 | |
| 9600 | // We return "" on error. |
| 9601 | static std::string from_ascii_to_ascii(std::string_view ut8_string) { |
| 9602 | static const std::string error = ""; |
| 9603 | // copy and map |
| 9604 | // we could be more efficient by avoiding the copy when unnecessary. |
| 9605 | std::string mapped_string = std::string(ut8_string); |
| 9606 | ascii_map(mapped_string.data(), mapped_string.size()); |
| 9607 | std::string out; |
| 9608 | size_t label_start = 0; |
| 9609 | |
| 9610 | while (label_start != mapped_string.size()) { |
| 9611 | size_t loc_dot = mapped_string.find('.', label_start); |
| 9612 | bool is_last_label = (loc_dot == std::string_view::npos); |
| 9613 | size_t label_size = is_last_label ? mapped_string.size() - label_start |
| 9614 | : loc_dot - label_start; |
| 9615 | size_t label_size_with_dot = is_last_label ? label_size : label_size + 1; |
| 9616 | std::string_view label_view(mapped_string.data() + label_start, label_size); |
| 9617 | label_start += label_size_with_dot; |
| 9618 | if (label_size == 0) { |
| 9619 | // empty label? Nothing to do. |
| 9620 | } else if (label_view.starts_with("xn--")) { |
| 9621 | // The xn-- part is the expensive game. |
| 9622 | out.append(label_view); |
| 9623 | std::string_view puny_segment_ascii( |
| 9624 | out.data() + out.size() - label_view.size() + 4, |
| 9625 | label_view.size() - 4); |
| 9626 | std::u32string tmp_buffer; |
| 9627 | bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer); |
| 9628 | if (!is_ok) { |
| 9629 | return error; |
| 9630 | } |
| 9631 | // If the input is just ASCII, it should not have been encoded |
| 9632 | // as punycode. |
| 9633 | // https://github.com/whatwg/url/issues/760 |
| 9634 | if (is_ascii(tmp_buffer)) { |
| 9635 | return error; |
| 9636 | } |
| 9637 | std::u32string post_map = ada::idna::map(tmp_buffer); |
| 9638 | if (tmp_buffer != post_map) { |
| 9639 | return error; |
| 9640 | } |
| 9641 | std::u32string pre_normal = post_map; |
| 9642 | normalize(post_map); |
| 9643 | if (post_map != pre_normal) { |
| 9644 | return error; |
| 9645 | } |
| 9646 | if (post_map.empty()) { |
| 9647 | return error; |
| 9648 | } |
| 9649 | if (!is_label_valid(post_map)) { |
| 9650 | return error; |
| 9651 | } |
| 9652 | } else { |
| 9653 | out.append(label_view); |
| 9654 | } |
| 9655 | if (!is_last_label) { |
| 9656 | out.push_back('.'); |
| 9657 | } |
| 9658 | } |
no test coverage detected