| 8022 | } |
| 8023 | |
| 8024 | bool punycode_to_utf32(std::string_view input, std::u32string &out) { |
| 8025 | // See https://github.com/whatwg/url/issues/803 |
| 8026 | if (input.starts_with("xn--")) { |
| 8027 | return false; |
| 8028 | } |
| 8029 | int32_t written_out{0}; |
| 8030 | out.reserve(out.size() + input.size()); |
| 8031 | uint32_t n = initial_n; |
| 8032 | int32_t i = 0; |
| 8033 | int32_t bias = initial_bias; |
| 8034 | // grab ascii content |
| 8035 | size_t end_of_ascii = input.find_last_of('-'); |
| 8036 | if (end_of_ascii != std::string_view::npos) { |
| 8037 | for (uint8_t c : input.substr(0, end_of_ascii)) { |
| 8038 | if (c >= 0x80) { |
| 8039 | return false; |
| 8040 | } |
| 8041 | out.push_back(c); |
| 8042 | written_out++; |
| 8043 | } |
| 8044 | input.remove_prefix(end_of_ascii + 1); |
| 8045 | } |
| 8046 | while (!input.empty()) { |
| 8047 | int32_t oldi = i; |
| 8048 | int32_t w = 1; |
| 8049 | for (int32_t k = base;; k += base) { |
| 8050 | if (input.empty()) { |
| 8051 | return false; |
| 8052 | } |
| 8053 | uint8_t code_point = input.front(); |
| 8054 | input.remove_prefix(1); |
| 8055 | int32_t digit = char_to_digit_value(code_point); |
| 8056 | if (digit < 0) { |
| 8057 | return false; |
| 8058 | } |
| 8059 | if (digit > (0x7fffffff - i) / w) { |
| 8060 | return false; |
| 8061 | } |
| 8062 | i = i + digit * w; |
| 8063 | int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; |
| 8064 | if (digit < t) { |
| 8065 | break; |
| 8066 | } |
| 8067 | if (w > 0x7fffffff / (base - t)) { |
| 8068 | return false; |
| 8069 | } |
| 8070 | w = w * (base - t); |
| 8071 | } |
| 8072 | bias = adapt(i - oldi, written_out + 1, oldi == 0); |
| 8073 | if (i / (written_out + 1) > int32_t(0x7fffffff - n)) { |
| 8074 | return false; |
| 8075 | } |
| 8076 | n = n + i / (written_out + 1); |
| 8077 | i = i % (written_out + 1); |
| 8078 | if (n < 0x80) { |
| 8079 | return false; |
| 8080 | } |
| 8081 | out.insert(out.begin() + i, n); |