Skip to content

Commit 99161b0

Browse files
XadillaXtargos
authored andcommitted
url,src: simplify ipv6 logic by using uv_inet_pton
PR-URL: #38842 Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 9bf9ddb commit 99161b0

File tree

1 file changed

+17
-108
lines changed

1 file changed

+17
-108
lines changed

src/node_url.cc

+17-108
Original file line numberDiff line numberDiff line change
@@ -797,119 +797,28 @@ bool ToASCII(const std::string& input, std::string* output) {
797797
}
798798
#endif
799799

800+
#define NS_IN6ADDRSZ 16
801+
800802
void URLHost::ParseIPv6Host(const char* input, size_t length) {
801803
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-
}
897804

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) {
911814
return;
912815
}
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+
913822
type_ = HostType::H_IPV6;
914823
}
915824

0 commit comments

Comments
 (0)