Browse Source

url: disallow invalid IPv4 in IPv6 parser

Fixes: https://github.com/nodejs/node/issues/10655
PR-URL: https://github.com/nodejs/node/pull/12315
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
v6
Daijiro Wachi 8 years ago
parent
commit
1b99d8ffe9
  1. 26
      src/node_url.cc
  2. 144
      test/fixtures/url-setter-tests.js
  3. 40
      test/fixtures/url-tests.js

26
src/node_url.cc

@ -110,7 +110,7 @@ namespace url {
uint16_t* compress_pointer = nullptr;
const char* pointer = input;
const char* end = pointer + length;
unsigned value, len, swaps, dots;
unsigned value, len, swaps, numbers_seen;
char ch = pointer < end ? pointer[0] : kEOL;
if (ch == ':') {
if (length < 2 || pointer[1] != ':')
@ -148,9 +148,17 @@ namespace url {
ch = pointer < end ? pointer[0] : kEOL;
if (piece_pointer > last_piece - 2)
goto end;
dots = 0;
numbers_seen = 0;
while (ch != kEOL) {
value = 0xffffffff;
if (numbers_seen > 0) {
if (ch == '.' && numbers_seen < 4) {
pointer++;
ch = pointer < end ? pointer[0] : kEOL;
} else {
goto end;
}
}
if (!ASCII_DIGIT(ch))
goto end;
while (ASCII_DIGIT(ch)) {
@ -167,19 +175,13 @@ namespace url {
pointer++;
ch = pointer < end ? pointer[0] : kEOL;
}
if (dots < 3 && ch != '.')
goto end;
*piece_pointer = *piece_pointer * 0x100 + value;
if (dots & 0x1)
numbers_seen++;
if (numbers_seen == 2 || numbers_seen == 4)
piece_pointer++;
if (ch != kEOL) {
pointer++;
ch = pointer < end ? pointer[0] : kEOL;
}
if (dots == 3 && ch != kEOL)
goto end;
dots++;
}
if (numbers_seen != 4)
goto end;
continue;
case ':':
pointer++;

144
test/fixtures/url-setter-tests.js

@ -880,42 +880,42 @@ module.exports =
"hostname": "example.net"
}
},
// {
// "href": "http://example.net/",
// "new_value": "[::1.2.3.4x]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
// {
// "href": "http://example.net/",
// "new_value": "[::1.2.3.]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
// {
// "href": "http://example.net/",
// "new_value": "[::1.2.]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
// {
// "href": "http://example.net/",
// "new_value": "[::1.]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
{
"href": "http://example.net/",
"new_value": "[::1.2.3.4x]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
{
"href": "http://example.net/",
"new_value": "[::1.2.3.]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
{
"href": "http://example.net/",
"new_value": "[::1.2.]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
{
"href": "http://example.net/",
"new_value": "[::1.]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
// {
// "href": "file://y/",
// "new_value": "x:123",
@ -1214,42 +1214,42 @@ module.exports =
"hostname": "example.net"
}
},
// {
// "href": "http://example.net/",
// "new_value": "[::1.2.3.4x]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
// {
// "href": "http://example.net/",
// "new_value": "[::1.2.3.]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
// {
// "href": "http://example.net/",
// "new_value": "[::1.2.]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
// {
// "href": "http://example.net/",
// "new_value": "[::1.]",
// "expected": {
// "href": "http://example.net/",
// "host": "example.net",
// "hostname": "example.net"
// }
// },
{
"href": "http://example.net/",
"new_value": "[::1.2.3.4x]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
{
"href": "http://example.net/",
"new_value": "[::1.2.3.]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
{
"href": "http://example.net/",
"new_value": "[::1.2.]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
{
"href": "http://example.net/",
"new_value": "[::1.]",
"expected": {
"href": "http://example.net/",
"host": "example.net",
"hostname": "example.net"
}
},
// {
// "href": "file://y/",
// "new_value": "x:123",

40
test/fixtures/url-tests.js

@ -3800,26 +3800,26 @@ module.exports =
"base": "http://other.com/",
"failure": true
},
// {
// "input": "http://[::1.2.3.4x]",
// "base": "http://other.com/",
// "failure": true
// },
// {
// "input": "http://[::1.2.3.]",
// "base": "http://other.com/",
// "failure": true
// },
// {
// "input": "http://[::1.2.]",
// "base": "http://other.com/",
// "failure": true
// },
// {
// "input": "http://[::1.]",
// "base": "http://other.com/",
// "failure": true
// },
{
"input": "http://[::1.2.3.4x]",
"base": "http://other.com/",
"failure": true
},
{
"input": "http://[::1.2.3.]",
"base": "http://other.com/",
"failure": true
},
{
"input": "http://[::1.2.]",
"base": "http://other.com/",
"failure": true
},
{
"input": "http://[::1.]",
"base": "http://other.com/",
"failure": true
},
"Misc Unicode",
{
"input": "http://foo:💩@example.com/bar",

Loading…
Cancel
Save