| 7900 | } |
| 7901 | |
| 7902 | bool punycode_to_utf32(std::string_view input, std::u32string &out) { |
| 7903 | // See https://github.com/whatwg/url/issues/803 |
| 7904 | if (input.starts_with("xn--")) { |
| 7905 | return false; |
| 7906 | } |
| 7907 | int32_t written_out{0}; |
| 7908 | out.reserve(out.size() + input.size()); |
| 7909 | uint32_t n = initial_n; |
| 7910 | int32_t i = 0; |
| 7911 | int32_t bias = initial_bias; |
| 7912 | // grab ascii content |
| 7913 | size_t end_of_ascii = input.find_last_of('-'); |
| 7914 | if (end_of_ascii != std::string_view::npos) { |
| 7915 | for (uint8_t c : input.substr(0, end_of_ascii)) { |
| 7916 | if (c >= 0x80) { |
| 7917 | return false; |
| 7918 | } |
| 7919 | out.push_back(c); |
| 7920 | written_out++; |
| 7921 | } |
| 7922 | input.remove_prefix(end_of_ascii + 1); |
| 7923 | } |
| 7924 | while (!input.empty()) { |
| 7925 | int32_t oldi = i; |
| 7926 | int32_t w = 1; |
| 7927 | for (int32_t k = base;; k += base) { |
| 7928 | if (input.empty()) { |
| 7929 | return false; |
| 7930 | } |
| 7931 | uint8_t code_point = input.front(); |
| 7932 | input.remove_prefix(1); |
| 7933 | int32_t digit = char_to_digit_value(code_point); |
| 7934 | if (digit < 0) { |
| 7935 | return false; |
| 7936 | } |
| 7937 | if (digit > (0x7fffffff - i) / w) { |
| 7938 | return false; |
| 7939 | } |
| 7940 | i = i + digit * w; |
| 7941 | int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; |
| 7942 | if (digit < t) { |
| 7943 | break; |
| 7944 | } |
| 7945 | if (w > 0x7fffffff / (base - t)) { |
| 7946 | return false; |
| 7947 | } |
| 7948 | w = w * (base - t); |
| 7949 | } |
| 7950 | bias = adapt(i - oldi, written_out + 1, oldi == 0); |
| 7951 | if (i / (written_out + 1) > int32_t(0x7fffffff - n)) { |
| 7952 | return false; |
| 7953 | } |
| 7954 | n = n + i / (written_out + 1); |
| 7955 | i = i % (written_out + 1); |
| 7956 | if (n < 0x80) { |
| 7957 | return false; |
| 7958 | } |
| 7959 | out.insert(out.begin() + i, n); |
no test coverage detected