Skip to content

Commit 29531d2

Browse files
watildeevanlucas
authored andcommitted
url: disallow invalid IPv4 in IPv6 parser
PR-URL: #12507 Fixes: #10655 Reviewed-By: James M Snell <[email protected]>
1 parent ffb2ef4 commit 29531d2

File tree

3 files changed

+106
-104
lines changed

3 files changed

+106
-104
lines changed

src/node_url.cc

+14-12
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ namespace url {
110110
uint16_t* compress_pointer = nullptr;
111111
const char* pointer = input;
112112
const char* end = pointer + length;
113-
unsigned value, len, swaps, dots;
113+
unsigned value, len, swaps, numbers_seen;
114114
char ch = pointer < end ? pointer[0] : kEOL;
115115
if (ch == ':') {
116116
if (length < 2 || pointer[1] != ':')
@@ -148,9 +148,17 @@ namespace url {
148148
ch = pointer < end ? pointer[0] : kEOL;
149149
if (piece_pointer > last_piece - 2)
150150
goto end;
151-
dots = 0;
151+
numbers_seen = 0;
152152
while (ch != kEOL) {
153153
value = 0xffffffff;
154+
if (numbers_seen > 0) {
155+
if (ch == '.' && numbers_seen < 4) {
156+
pointer++;
157+
ch = pointer < end ? pointer[0] : kEOL;
158+
} else {
159+
goto end;
160+
}
161+
}
154162
if (!ASCII_DIGIT(ch))
155163
goto end;
156164
while (ASCII_DIGIT(ch)) {
@@ -167,19 +175,13 @@ namespace url {
167175
pointer++;
168176
ch = pointer < end ? pointer[0] : kEOL;
169177
}
170-
if (dots < 3 && ch != '.')
171-
goto end;
172178
*piece_pointer = *piece_pointer * 0x100 + value;
173-
if (dots & 0x1)
179+
numbers_seen++;
180+
if (numbers_seen == 2 || numbers_seen == 4)
174181
piece_pointer++;
175-
if (ch != kEOL) {
176-
pointer++;
177-
ch = pointer < end ? pointer[0] : kEOL;
178-
}
179-
if (dots == 3 && ch != kEOL)
180-
goto end;
181-
dots++;
182182
}
183+
if (numbers_seen != 4)
184+
goto end;
183185
continue;
184186
case ':':
185187
pointer++;

test/fixtures/url-setter-tests.js

+72-72
Original file line numberDiff line numberDiff line change
@@ -880,42 +880,42 @@ module.exports =
880880
"hostname": "example.net"
881881
}
882882
},
883-
// {
884-
// "href": "http://example.net/",
885-
// "new_value": "[::1.2.3.4x]",
886-
// "expected": {
887-
// "href": "http://example.net/",
888-
// "host": "example.net",
889-
// "hostname": "example.net"
890-
// }
891-
// },
892-
// {
893-
// "href": "http://example.net/",
894-
// "new_value": "[::1.2.3.]",
895-
// "expected": {
896-
// "href": "http://example.net/",
897-
// "host": "example.net",
898-
// "hostname": "example.net"
899-
// }
900-
// },
901-
// {
902-
// "href": "http://example.net/",
903-
// "new_value": "[::1.2.]",
904-
// "expected": {
905-
// "href": "http://example.net/",
906-
// "host": "example.net",
907-
// "hostname": "example.net"
908-
// }
909-
// },
910-
// {
911-
// "href": "http://example.net/",
912-
// "new_value": "[::1.]",
913-
// "expected": {
914-
// "href": "http://example.net/",
915-
// "host": "example.net",
916-
// "hostname": "example.net"
917-
// }
918-
// },
883+
{
884+
"href": "http://example.net/",
885+
"new_value": "[::1.2.3.4x]",
886+
"expected": {
887+
"href": "http://example.net/",
888+
"host": "example.net",
889+
"hostname": "example.net"
890+
}
891+
},
892+
{
893+
"href": "http://example.net/",
894+
"new_value": "[::1.2.3.]",
895+
"expected": {
896+
"href": "http://example.net/",
897+
"host": "example.net",
898+
"hostname": "example.net"
899+
}
900+
},
901+
{
902+
"href": "http://example.net/",
903+
"new_value": "[::1.2.]",
904+
"expected": {
905+
"href": "http://example.net/",
906+
"host": "example.net",
907+
"hostname": "example.net"
908+
}
909+
},
910+
{
911+
"href": "http://example.net/",
912+
"new_value": "[::1.]",
913+
"expected": {
914+
"href": "http://example.net/",
915+
"host": "example.net",
916+
"hostname": "example.net"
917+
}
918+
},
919919
// {
920920
// "href": "file://y/",
921921
// "new_value": "x:123",
@@ -1214,42 +1214,42 @@ module.exports =
12141214
"hostname": "example.net"
12151215
}
12161216
},
1217-
// {
1218-
// "href": "http://example.net/",
1219-
// "new_value": "[::1.2.3.4x]",
1220-
// "expected": {
1221-
// "href": "http://example.net/",
1222-
// "host": "example.net",
1223-
// "hostname": "example.net"
1224-
// }
1225-
// },
1226-
// {
1227-
// "href": "http://example.net/",
1228-
// "new_value": "[::1.2.3.]",
1229-
// "expected": {
1230-
// "href": "http://example.net/",
1231-
// "host": "example.net",
1232-
// "hostname": "example.net"
1233-
// }
1234-
// },
1235-
// {
1236-
// "href": "http://example.net/",
1237-
// "new_value": "[::1.2.]",
1238-
// "expected": {
1239-
// "href": "http://example.net/",
1240-
// "host": "example.net",
1241-
// "hostname": "example.net"
1242-
// }
1243-
// },
1244-
// {
1245-
// "href": "http://example.net/",
1246-
// "new_value": "[::1.]",
1247-
// "expected": {
1248-
// "href": "http://example.net/",
1249-
// "host": "example.net",
1250-
// "hostname": "example.net"
1251-
// }
1252-
// },
1217+
{
1218+
"href": "http://example.net/",
1219+
"new_value": "[::1.2.3.4x]",
1220+
"expected": {
1221+
"href": "http://example.net/",
1222+
"host": "example.net",
1223+
"hostname": "example.net"
1224+
}
1225+
},
1226+
{
1227+
"href": "http://example.net/",
1228+
"new_value": "[::1.2.3.]",
1229+
"expected": {
1230+
"href": "http://example.net/",
1231+
"host": "example.net",
1232+
"hostname": "example.net"
1233+
}
1234+
},
1235+
{
1236+
"href": "http://example.net/",
1237+
"new_value": "[::1.2.]",
1238+
"expected": {
1239+
"href": "http://example.net/",
1240+
"host": "example.net",
1241+
"hostname": "example.net"
1242+
}
1243+
},
1244+
{
1245+
"href": "http://example.net/",
1246+
"new_value": "[::1.]",
1247+
"expected": {
1248+
"href": "http://example.net/",
1249+
"host": "example.net",
1250+
"hostname": "example.net"
1251+
}
1252+
},
12531253
// {
12541254
// "href": "file://y/",
12551255
// "new_value": "x:123",

test/fixtures/url-tests.js

+20-20
Original file line numberDiff line numberDiff line change
@@ -3800,26 +3800,26 @@ module.exports =
38003800
"base": "http://other.com/",
38013801
"failure": true
38023802
},
3803-
// {
3804-
// "input": "http://[::1.2.3.4x]",
3805-
// "base": "http://other.com/",
3806-
// "failure": true
3807-
// },
3808-
// {
3809-
// "input": "http://[::1.2.3.]",
3810-
// "base": "http://other.com/",
3811-
// "failure": true
3812-
// },
3813-
// {
3814-
// "input": "http://[::1.2.]",
3815-
// "base": "http://other.com/",
3816-
// "failure": true
3817-
// },
3818-
// {
3819-
// "input": "http://[::1.]",
3820-
// "base": "http://other.com/",
3821-
// "failure": true
3822-
// },
3803+
{
3804+
"input": "http://[::1.2.3.4x]",
3805+
"base": "http://other.com/",
3806+
"failure": true
3807+
},
3808+
{
3809+
"input": "http://[::1.2.3.]",
3810+
"base": "http://other.com/",
3811+
"failure": true
3812+
},
3813+
{
3814+
"input": "http://[::1.2.]",
3815+
"base": "http://other.com/",
3816+
"failure": true
3817+
},
3818+
{
3819+
"input": "http://[::1.]",
3820+
"base": "http://other.com/",
3821+
"failure": true
3822+
},
38233823
"Misc Unicode",
38243824
{
38253825
"input": "http://foo:💩@example.com/bar",

0 commit comments

Comments
 (0)