Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 99161b0

Browse filesBrowse 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
Copy full SHA for 99161b0

File tree

Expand file treeCollapse file tree

1 file changed

+17
-108
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+17
-108
lines changed
Open diff view settings
Collapse file

‎src/node_url.cc‎

Copy file name to clipboardExpand all lines: src/node_url.cc
+17-108Lines changed: 17 additions & 108 deletions
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.