Module: wine Branch: master Commit: 90d975ac1ed5da6de23d4edb732c0d08954b000a URL: https://gitlab.winehq.org/wine/wine/-/commit/90d975ac1ed5da6de23d4edb732c0d0...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Jan 10 14:56:50 2023 +0100
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
---
dlls/ntdll/rtl.c | 2 -- dlls/ntdll/tests/rtl.c | 45 ++++++++++++++++++++++++++++---------------- dlls/urlmon/tests/uri.c | 2 -- dlls/ws2_32/tests/protocol.c | 14 +++++++------- 4 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 59dde6359e3..84488ea1d81 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -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 (;;) diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 1e5e8c2580c..c2ca8ea11a7 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -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]); } }
diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c index a3161b8e401..18ea01e64c2 100644 --- a/dlls/urlmon/tests/uri.c +++ b/dlls/urlmon/tests/uri.c @@ -5118,8 +5118,6 @@ static const invalid_uri invalid_uri_tests[] = { {"http://%5B1:192.0.1.0%5D%22,0,FALSE%7D, /* Not allowed to have partial IPv4 in IPv6. */ {"http://%5B::192.0%5D%22,0,FALSE%7D, - /* Can't have elision of 1 h16 at beginning of address. */ - {"http://%5B::2:3:4:5:6:7:8%5D%22,0,FALSE%7D, /* Expects a valid IP Literal. */ {"ftp://[not.valid.uri]/",0,FALSE}, /* Expects valid port for a known scheme type. */ diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c index 01b4c2ba71e..34c0dbb0858 100644 --- a/dlls/ws2_32/tests/protocol.c +++ b/dlls/ws2_32/tests/protocol.c @@ -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],