| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -797,119 +797,28 @@ bool ToASCII(const std::string& input, std::string* output) { | |||
| 797 | 797 | } | |
| 798 | 798 | #endif | |
| 799 | 799 | ||
| 800 | + #define NS_IN6ADDRSZ 16 | ||
| 801 | + | ||
| 800 | 802 | void URLHost::ParseIPv6Host(const char* input, size_t length) { | |
| 801 | 803 | CHECK_EQ(type_, HostType::H_FAILED); | |
| 802 | - unsigned size = arraysize(value_.ipv6); | ||
| 803 | - for (unsigned n = 0; n < size; n++) | ||
| 804 | - value_.ipv6[n] = 0; | ||
| 805 | - uint16_t* piece_pointer = &value_.ipv6[0]; | ||
| 806 | - uint16_t* const buffer_end = piece_pointer + size; | ||
| 807 | - uint16_t* compress_pointer = nullptr; | ||
| 808 | - const char* pointer = input; | ||
| 809 | - const char* end = pointer + length; | ||
| 810 | - unsigned value, len, numbers_seen; | ||
| 811 | - char ch = pointer < end ? pointer[0] : kEOL; | ||
| 812 | - if (ch == ':') { | ||
| 813 | - if (length < 2 || pointer[1] != ':') | ||
| 814 | - return; | ||
| 815 | - pointer += 2; | ||
| 816 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 817 | - piece_pointer++; | ||
| 818 | - compress_pointer = piece_pointer; | ||
| 819 | - } | ||
| 820 | - while (ch != kEOL) { | ||
| 821 | - if (piece_pointer >= buffer_end) | ||
| 822 | - return; | ||
| 823 | - if (ch == ':') { | ||
| 824 | - if (compress_pointer != nullptr) | ||
| 825 | - return; | ||
| 826 | - pointer++; | ||
| 827 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 828 | - piece_pointer++; | ||
| 829 | - compress_pointer = piece_pointer; | ||
| 830 | - continue; | ||
| 831 | - } | ||
| 832 | - value = 0; | ||
| 833 | - len = 0; | ||
| 834 | - while (len < 4 && IsASCIIHexDigit(ch)) { | ||
| 835 | - value = value * 0x10 + hex2bin(ch); | ||
| 836 | - pointer++; | ||
| 837 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 838 | - len++; | ||
| 839 | - } | ||
| 840 | - switch (ch) { | ||
| 841 | - case '.': | ||
| 842 | - if (len == 0) | ||
| 843 | - return; | ||
| 844 | - pointer -= len; | ||
| 845 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 846 | - if (piece_pointer > buffer_end - 2) | ||
| 847 | - return; | ||
| 848 | - numbers_seen = 0; | ||
| 849 | - while (ch != kEOL) { | ||
| 850 | - value = 0xffffffff; | ||
| 851 | - if (numbers_seen > 0) { | ||
| 852 | - if (ch == '.' && numbers_seen < 4) { | ||
| 853 | - pointer++; | ||
| 854 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 855 | - } else { | ||
| 856 | - return; | ||
| 857 | - } | ||
| 858 | - } | ||
| 859 | - if (!IsASCIIDigit(ch)) | ||
| 860 | - return; | ||
| 861 | - while (IsASCIIDigit(ch)) { | ||
| 862 | - unsigned number = ch - '0'; | ||
| 863 | - if (value == 0xffffffff) { | ||
| 864 | - value = number; | ||
| 865 | - } else if (value == 0) { | ||
| 866 | - return; | ||
| 867 | - } else { | ||
| 868 | - value = value * 10 + number; | ||
| 869 | - } | ||
| 870 | - if (value > 255) | ||
| 871 | - return; | ||
| 872 | - pointer++; | ||
| 873 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 874 | - } | ||
| 875 | - *piece_pointer = *piece_pointer * 0x100 + value; | ||
| 876 | - numbers_seen++; | ||
| 877 | - if (numbers_seen == 2 || numbers_seen == 4) | ||
| 878 | - piece_pointer++; | ||
| 879 | - } | ||
| 880 | - if (numbers_seen != 4) | ||
| 881 | - return; | ||
| 882 | - continue; | ||
| 883 | - case ':': | ||
| 884 | - pointer++; | ||
| 885 | - ch = pointer < end ? pointer[0] : kEOL; | ||
| 886 | - if (ch == kEOL) | ||
| 887 | - return; | ||
| 888 | - break; | ||
| 889 | - case kEOL: | ||
| 890 | - break; | ||
| 891 | - default: | ||
| 892 | - return; | ||
| 893 | - } | ||
| 894 | - *piece_pointer = value; | ||
| 895 | - piece_pointer++; | ||
| 896 | - } | ||
| 897 | 804 | ||
| 898 | - if (compress_pointer != nullptr) { | ||
| 899 | - int64_t swaps = piece_pointer - compress_pointer; | ||
| 900 | - piece_pointer = buffer_end - 1; | ||
| 901 | - while (piece_pointer != &value_.ipv6[0] && swaps > 0) { | ||
| 902 | - uint16_t temp = *piece_pointer; | ||
| 903 | - uint16_t* swap_piece = compress_pointer + swaps - 1; | ||
| 904 | - *piece_pointer = *swap_piece; | ||
| 905 | - *swap_piece = temp; | ||
| 906 | - piece_pointer--; | ||
| 907 | - swaps--; | ||
| 908 | - } | ||
| 909 | - } else if (compress_pointer == nullptr && | ||
| 910 | - piece_pointer != buffer_end) { | ||
| 805 | + unsigned char buf[sizeof(struct in6_addr)]; | ||
| 806 | + MaybeStackBuffer<char> ipv6(length + 1); | ||
| 807 | + *(*ipv6 + length) = 0; | ||
| 808 | + memset(buf, 0, sizeof(buf)); | ||
| 809 | + memcpy(*ipv6, input, sizeof(const char) * length); | ||
| 810 | + | ||
| 811 | + int ret = uv_inet_pton(AF_INET6, *ipv6, buf); | ||
| 812 | + | ||
| 813 | + if (ret != 0) { | ||
| 911 | 814 | return; | |
| 912 | 815 | } | |
| 816 | + | ||
| 817 | + // Ref: https://sourceware.org/git/?p=glibc.git;a=blob;f=resolv/inet_ntop.c;h=c4d38c0f951013e51a4fc6eaa8a9b82e146abe5a;hb=HEAD#l119 | ||
| 818 | + for (int i = 0; i < NS_IN6ADDRSZ; i += 2) { | ||
| 819 | + value_.ipv6[i >> 1] = (buf[i] << 8) | buf[i + 1]; | ||
| 820 | + } | ||
| 821 | + | ||
| 913 | 822 | type_ = HostType::H_IPV6; | |
| 914 | 823 | } | |
| 915 | 824 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments