Commit 90d975ac authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

ntdll: Conform to Windows 11 behavior in RtlIpv6StringToAddress().

Also fixes test failures on Windows 11. Wine-Bug: https://bugs.winehq.org//show_bug.cgi?id=54045
parent a0985cbf
......@@ -1126,9 +1126,7 @@ static NTSTATUS ipv6_string_to_address(const WCHAR *str, BOOL ex,
{
if (str[1] != ':') goto error;
str++;
/* Windows bug: a double colon at the beginning is treated as 4 bytes of zeros instead of 2 */
address->u.Word[0] = 0;
n_bytes = 2;
}
for (;;)
......
......@@ -1409,7 +1409,7 @@ static const struct
/* win_broken: XP and Vista do not handle this correctly
ex_fail: Ex function does need the string to be terminated, non-Ex does not.
ex_skip: test doesn't make sense for Ex (f.e. it's invalid for non-Ex but valid for Ex) */
enum { normal_6, win_broken_6 = 1, ex_fail_6 = 2, ex_skip_6 = 4 } flags;
enum { normal_6, win_broken_6 = 1, ex_fail_6 = 2, ex_skip_6 = 4, win_extra_zero = 8 } flags;
} ipv6_tests[] =
{
{ "0000:0000:0000:0000:0000:0000:0000:0000", STATUS_SUCCESS, 39,
......@@ -1576,12 +1576,12 @@ static const struct
{ 0, 0, 0, 0, 0, 0, 0, 0 } },
{ "::0:0:0:0:0:0", STATUS_SUCCESS, 13,
{ 0, 0, 0, 0, 0, 0, 0, 0 } },
/* this one and the next one are incorrectly parsed by windows,
/* this one and the next one are incorrectly parsed before Windows 11,
it adds one zero too many in front, cutting off the last digit. */
{ "::0:0:0:0:0:0:0", STATUS_SUCCESS, 13,
{ 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
{ "::0:a:b:c:d:e:f", STATUS_SUCCESS, 13,
{ 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 }, ex_fail_6 },
{ "::0:0:0:0:0:0:0", STATUS_SUCCESS, 15,
{ 0, 0, 0, 0, 0, 0, 0, 0 }, win_broken_6|win_extra_zero },
{ "::0:a:b:c:d:e:f", STATUS_SUCCESS, 15,
{ 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, 0xf00 }, win_broken_6|win_extra_zero },
{ "::123.123.123.123", STATUS_SUCCESS, 17,
{ 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } },
{ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39,
......@@ -2103,19 +2103,32 @@ static void test_RtlIpv6StringToAddress(void)
}
else
{
ok(terminator == ipv6_tests[i].address + ipv6_tests[i].terminator_offset,
"[%s] terminator = %p, expected %p\n",
ipv6_tests[i].address, terminator, ipv6_tests[i].address + ipv6_tests[i].terminator_offset);
if (ipv6_tests[i].flags & win_extra_zero)
ok(terminator == ipv6_tests[i].address + ipv6_tests[i].terminator_offset ||
broken(terminator != ipv6_tests[i].address + ipv6_tests[i].terminator_offset),
"[%s] terminator = %p, expected %p\n",
ipv6_tests[i].address, terminator, ipv6_tests[i].address + ipv6_tests[i].terminator_offset);
else
ok(terminator == ipv6_tests[i].address + ipv6_tests[i].terminator_offset,
"[%s] terminator = %p, expected %p\n",
ipv6_tests[i].address, terminator, ipv6_tests[i].address + ipv6_tests[i].terminator_offset);
}
init_ip6(&expected_ip, ipv6_tests[i].ip);
ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
"[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
ipv6_tests[i].address,
ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
if (ipv6_tests[i].flags & win_extra_zero)
ok(!memcmp(&ip, &expected_ip, sizeof(ip)) || broken(memcmp(&ip, &expected_ip, sizeof(ip))),
"[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
ipv6_tests[i].address, ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
else
ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
"[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
ipv6_tests[i].address, ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
}
}
......
......@@ -5118,8 +5118,6 @@ static const invalid_uri invalid_uri_tests[] = {
{"http://[1:192.0.1.0]",0,FALSE},
/* Not allowed to have partial IPv4 in IPv6. */
{"http://[::192.0]",0,FALSE},
/* Can't have elision of 1 h16 at beginning of address. */
{"http://[::2:3:4:5:6:7:8]",0,FALSE},
/* Expects a valid IP Literal. */
{"ftp://[not.valid.uri]/",0,FALSE},
/* Expects valid port for a known scheme type. */
......
......@@ -1078,12 +1078,12 @@ static void test_inet_pton(void)
memset(addr, 0xab, sizeof(addr));
ret = p_inet_pton(AF_INET6, ipv6_tests[i].input, addr);
if (ipv6_tests[i].broken)
todo_wine_if (i == 82 || i == 83) ok(ret == ipv6_tests[i].ret || broken(ret == ipv6_tests[i].broken_ret), "got %d\n", ret);
ok(ret == ipv6_tests[i].ret || broken(ret == ipv6_tests[i].broken_ret), "got %d\n", ret);
else
ok(ret == ipv6_tests[i].ret, "got %d\n", ret);
ok(WSAGetLastError() == 0xdeadbeef, "got error %u\n", WSAGetLastError());
if (ipv6_tests[i].broken)
todo_wine_if (i == 83) ok(!memcmp(addr, ipv6_tests[i].addr, sizeof(addr)) || broken(memcmp(addr, ipv6_tests[i].addr, sizeof(addr))),
ok(!memcmp(addr, ipv6_tests[i].addr, sizeof(addr)) || broken(memcmp(addr, ipv6_tests[i].addr, sizeof(addr))),
"address didn't match\n");
else
ok(!memcmp(addr, ipv6_tests[i].addr, sizeof(addr)), "address didn't match\n");
......@@ -1093,12 +1093,12 @@ static void test_inet_pton(void)
memset(addr, 0xab, sizeof(addr));
ret = pInetPtonW(AF_INET6, inputW, addr);
if (ipv6_tests[i].broken)
todo_wine ok(ret == ipv6_tests[i].ret || broken(ret == ipv6_tests[i].broken_ret), "got %d\n", ret);
ok(ret == ipv6_tests[i].ret || broken(ret == ipv6_tests[i].broken_ret), "got %d\n", ret);
else
ok(ret == ipv6_tests[i].ret, "got %d\n", ret);
ok(WSAGetLastError() == (ret ? 0xdeadbeef : WSAEINVAL), "got error %u\n", WSAGetLastError());
if (ipv6_tests[i].broken)
todo_wine_if (i == 83) ok(!memcmp(addr, ipv6_tests[i].addr, sizeof(addr)) || broken(memcmp(addr, ipv6_tests[i].addr, sizeof(addr))),
ok(!memcmp(addr, ipv6_tests[i].addr, sizeof(addr)) || broken(memcmp(addr, ipv6_tests[i].addr, sizeof(addr))),
"address didn't match\n");
else
ok(!memcmp(addr, ipv6_tests[i].addr, sizeof(addr)), "address didn't match\n");
......@@ -1561,11 +1561,11 @@ static void test_WSAStringToAddress(void)
if (ipv6_tests[j].broken)
{
todo_wine ok( ret == (ipv6_tests[j].error ? SOCKET_ERROR : 0) ||
ok( ret == (ipv6_tests[j].error ? SOCKET_ERROR : 0) ||
broken(ret == (ipv6_tests[j].broken_error ? SOCKET_ERROR : 0)), "got %d\n", ret );
todo_wine ok( WSAGetLastError() == ipv6_tests[j].error ||
ok( WSAGetLastError() == ipv6_tests[j].error ||
broken(WSAGetLastError() == ipv6_tests[j].broken_error), "got error %d\n", WSAGetLastError() );
todo_wine ok( !memcmp( &sockaddr6.sin6_addr, ipv6_tests[j].address, sizeof(sockaddr6.sin6_addr) ) ||
ok( !memcmp( &sockaddr6.sin6_addr, ipv6_tests[j].address, sizeof(sockaddr6.sin6_addr) ) ||
broken(memcmp( &sockaddr6.sin6_addr, ipv6_tests[j].address, sizeof(sockaddr6.sin6_addr) )),
"got addr %x:%x:%x:%x:%x:%x:%x:%x\n",
sockaddr6.sin6_addr.s6_words[0], sockaddr6.sin6_addr.s6_words[1],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment