We return "" on error.
| 9661 | |
| 9662 | // We return "" on error. |
| 9663 | std::string to_ascii(std::string_view ut8_string) { |
| 9664 | if (is_ascii(ut8_string)) { |
| 9665 | return from_ascii_to_ascii(ut8_string); |
| 9666 | } |
| 9667 | static const std::string error = ""; |
| 9668 | // We convert to UTF-32 |
| 9669 | |
| 9670 | #ifdef ADA_USE_SIMDUTF |
| 9671 | size_t utf32_length = |
| 9672 | simdutf::utf32_length_from_utf8(ut8_string.data(), ut8_string.size()); |
| 9673 | std::u32string utf32(utf32_length, '\0'); |
| 9674 | size_t actual_utf32_length = simdutf::convert_utf8_to_utf32( |
| 9675 | ut8_string.data(), ut8_string.size(), utf32.data()); |
| 9676 | #else |
| 9677 | size_t utf32_length = |
| 9678 | ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size()); |
| 9679 | std::u32string utf32(utf32_length, '\0'); |
| 9680 | size_t actual_utf32_length = ada::idna::utf8_to_utf32( |
| 9681 | ut8_string.data(), ut8_string.size(), utf32.data()); |
| 9682 | #endif |
| 9683 | if (actual_utf32_length == 0) { |
| 9684 | return error; |
| 9685 | } |
| 9686 | // mapping |
| 9687 | utf32 = ada::idna::map(utf32); |
| 9688 | normalize(utf32); |
| 9689 | std::string out; |
| 9690 | size_t label_start = 0; |
| 9691 | |
| 9692 | while (label_start != utf32.size()) { |
| 9693 | size_t loc_dot = utf32.find('.', label_start); |
| 9694 | bool is_last_label = (loc_dot == std::string_view::npos); |
| 9695 | size_t label_size = |
| 9696 | is_last_label ? utf32.size() - label_start : loc_dot - label_start; |
| 9697 | size_t label_size_with_dot = is_last_label ? label_size : label_size + 1; |
| 9698 | std::u32string_view label_view(utf32.data() + label_start, label_size); |
| 9699 | label_start += label_size_with_dot; |
| 9700 | if (label_size == 0) { |
| 9701 | // empty label? Nothing to do. |
| 9702 | } else if (label_view.starts_with(U"xn--")) { |
| 9703 | // we do not need to check, e.g., Xn-- because mapping goes to lower case |
| 9704 | for (char32_t c : label_view) { |
| 9705 | if (c >= 0x80) { |
| 9706 | return error; |
| 9707 | } |
| 9708 | out += (unsigned char)(c); |
| 9709 | } |
| 9710 | std::string_view puny_segment_ascii( |
| 9711 | out.data() + out.size() - label_view.size() + 4, |
| 9712 | label_view.size() - 4); |
| 9713 | std::u32string tmp_buffer; |
| 9714 | bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer); |
| 9715 | if (!is_ok) { |
| 9716 | return error; |
| 9717 | } |
| 9718 | // If the input is just ASCII, it should not have been encoded |
| 9719 | // as punycode. |
| 9720 | // https://github.com/whatwg/url/issues/760 |
no test coverage detected