The imported algorithm is modified to match the tests.
Fixes a regression introduced by commit 671cf16f773e5dafc7edbf7766aed9e52e4e7b56.
Windows inet_addr() behaves basically the same as Unix inet_addr() which is different from inet_pton().
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - allow any space as terminator and add tests for that; - remove now duplicate inet_addr() tests from test_inet_pton (the main part of those didn't work due to missing brackets for '?' operator).
dlls/ws2_32/protocol.c | 52 ++++++++++++++++-- dlls/ws2_32/tests/protocol.c | 103 +++++++++++++++++++++++++++++++---- 2 files changed, 141 insertions(+), 14 deletions(-)
diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index 0f56b1604d8..6e7e8eee18a 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -1834,17 +1834,61 @@ int WINAPI WSAAddressToStringW( struct sockaddr *addr, DWORD addr_len, return 0; }
- /*********************************************************************** * inet_addr (ws2_32.11) */ u_long WINAPI inet_addr( const char *str ) { + unsigned long a[4] = { 0 }; + const char *s = str; + unsigned char *d; + unsigned int i; u_long addr; + char *z; + + TRACE( "str %s.\n", debugstr_a(str) ); + + if (!s) + { + SetLastError( WSAEFAULT ); + return INADDR_NONE; + } + + d = (unsigned char *)&addr; + + if (s[0] == ' ' && !s[1]) return 0;
- if (inet_pton( AF_INET, str, &addr ) == 1) - return addr; - return INADDR_NONE; + for (i = 0; i < 4; ++i) + { + a[i] = strtoul( s, &z, 0 ); + if (z == s || !isdigit( *s )) return INADDR_NONE; + if (!*z || isspace(*z)) break; + if (*z != '.') return INADDR_NONE; + s = z + 1; + } + + if (i == 4) return INADDR_NONE; + + switch (i) + { + case 0: + a[1] = a[0] & 0xffffff; + a[0] >>= 24; + /* fallthrough */ + case 1: + a[2] = a[1] & 0xffff; + a[1] >>= 16; + /* fallthrough */ + case 2: + a[3] = a[2] & 0xff; + a[2] >>= 8; + } + for (i = 0; i < 4; ++i) + { + if (a[i] > 255) return INADDR_NONE; + d[i] = a[i]; + } + return addr; }
diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c index 374fa01789d..9b3dec39dad 100644 --- a/dlls/ws2_32/tests/protocol.c +++ b/dlls/ws2_32/tests/protocol.c @@ -674,6 +674,98 @@ static void test_inet_ntoa(void) CloseHandle(thread); }
+static void test_inet_addr(void) +{ + static const struct + { + const char *input; + u_long addr; + } + tests[] = + { + {"1.2.3.4", 0x04030201}, + {"1 2 3 4", 0x01000000}, + {"1.2.3. 4", 0xffffffff}, + {"1.2.3 .4", 0x03000201}, + {"1.2.3 \xfe\xff", 0x03000201}, + {"3.4.5.6.7", 0xffffffff}, + {"3.4.5.6. 7", 0xffffffff}, + {"3.4.5.6 7", 0x06050403}, + {" 3.4.5.6", 0xffffffff}, + {"\t3.4.5.6", 0xffffffff}, + {"3.4.5.6 ", 0x06050403}, + {"3.4.5.6 ", 0x06050403}, + {"3. 4.5.6", 0xffffffff}, + {"3 .4.5.6", 0x03000000}, + {"1.2.3", 0x03000201}, + {".1.2.3", 0xffffffff}, + {"0.0.0.0", 0x00000000}, + {"", 0xffffffff}, + {" 0", 0xffffffff}, + {"0xa1a2b3b4 ", 0xb4b3a2a1}, + {".", 0xffffffff}, + {" ", 0x00000000}, + {"\t", 0xffffffff}, + {" ", 0xffffffff}, + {"127.127.127.255", 0xff7f7f7f}, + {"127.127.127.255:123", 0xffffffff}, + {"127.127.127.256", 0xffffffff}, + {"a", 0xffffffff}, + {"1.2.3.0xaA", 0xaa030201}, + {"1.1.1.0x", 0xffffffff}, + {"1.2.3.010", 0x08030201}, + {"1.2.3.00", 0x00030201}, + {"1.2.3.0a", 0xffffffff}, + {"1.1.1.0o10", 0xffffffff}, + {"1.1.1.0b10", 0xffffffff}, + {"1.1.1.-2", 0xffffffff}, + {"1", 0x01000000}, + {"1.2", 0x02000001}, + {"1.2.3", 0x03000201}, + {"203569230", 0x4e38220c}, + {"[0.1.2.3]", 0xffffffff}, + {"0x00010203", 0x03020100}, + {"0x2134", 0x34210000}, + {"1234BEEF", 0xffffffff}, + {"017700000001", 0x0100007f}, + {"0777", 0xff010000}, + {"2607:f0d0:1002:51::4", 0xffffffff}, + {"::177.32.45.20", 0xffffffff}, + {"::1/128", 0xffffffff}, + {"::1", 0xffffffff}, + {":1", 0xffffffff}, + }; + u_long addr, expected; + unsigned int i; + char str[32]; + + WSASetLastError(0xdeadbeef); + addr = inet_addr(NULL); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(addr == 0xffffffff, "got addr %#08x\n", addr); + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context( "Address %s, i %u", debugstr_a(tests[i].input), i ); + WSASetLastError(0xdeadbeef); + addr = inet_addr(tests[i].input); + ok(WSAGetLastError() == 0xdeadbeef, "got error %u\n", WSAGetLastError()); + ok(addr == tests[i].addr, "got addr %#08x\n", addr); + winetest_pop_context(); + } + + strcpy(str, "1.2.3"); + str[6] = 0; + for (i = 1; i < 256; ++i) + { + if (isdigit(i)) + continue; + str[5] = i; + expected = isspace(i) ? 0x03000201 : 0xffffffff; + addr = inet_addr(str); + ok(addr == expected, "got addr %#08x, expected %#08x, i %u\n", addr, expected, i); + } +} + static void test_inet_pton(void) { static const struct @@ -942,11 +1034,6 @@ static void test_inet_pton(void) ok(ret == -1, "got %d\n", ret); ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
- WSASetLastError(0xdeadbeef); - ret = inet_addr(NULL); - ok(ret == INADDR_NONE, "got %#x\n", ret); - ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); - for (i = 0; i < ARRAY_SIZE(ipv4_tests); ++i) { WCHAR inputW[32]; @@ -969,11 +1056,6 @@ static void test_inet_pton(void) ok(WSAGetLastError() == (ret ? 0xdeadbeef : WSAEINVAL), "got error %u\n", WSAGetLastError()); ok(addr == ipv4_tests[i].addr, "got addr %#08x\n", addr);
- WSASetLastError(0xdeadbeef); - addr = inet_addr(ipv4_tests[i].input); - ok(addr == ipv4_tests[i].ret ? ipv4_tests[i].addr : INADDR_NONE, "got addr %#08x\n", addr); - ok(WSAGetLastError() == 0xdeadbeef, "got error %u\n", WSAGetLastError()); - winetest_pop_context(); }
@@ -2871,6 +2953,7 @@ START_TEST( protocol ) test_WSALookupService();
test_inet_ntoa(); + test_inet_addr(); test_inet_pton(); test_addr_to_print(); test_WSAAddressToString();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=109679
Your paranoid android.
=== w8adm (32 bit report) ===
ws2_32: protocol.c:1816: Test failed: got 11001 expected success protocol.c:1817: Test failed: got 00000000
On 3/3/22 04:32, Paul Gofman wrote:
- allow any space as terminator and add tests for that;
Somehow the tests didn't seem to make it into this patch.
On 3/4/22 22:33, Zebediah Figura wrote:
On 3/3/22 04:32, Paul Gofman wrote:
- allow any space as terminator and add tests for that;
Somehow the tests didn't seem to make it into this patch.
Eh... I added the whole loop for that which tests all the possible characters in the end of the string?
+ } + + strcpy(str, "1.2.3"); + str[6] = 0; + for (i = 1; i < 256; ++i) + { + if (isdigit(i)) + continue; + str[5] = i; + expected = isspace(i) ? 0x03000201 : 0xffffffff; + addr = inet_addr(str); + ok(addr == expected, "got addr %#08x, expected %#08x, i %u\n", addr, expected, i); + } +} +
On 3/4/22 13:35, Paul Gofman wrote:
On 3/4/22 22:33, Zebediah Figura wrote:
On 3/3/22 04:32, Paul Gofman wrote:
- allow any space as terminator and add tests for that;
Somehow the tests didn't seem to make it into this patch.
Eh... I added the whole loop for that which tests all the possible characters in the end of the string?
+ }
+ strcpy(str, "1.2.3"); + str[6] = 0; + for (i = 1; i < 256; ++i) + { + if (isdigit(i)) + continue; + str[5] = i; + expected = isspace(i) ? 0x03000201 : 0xffffffff; + addr = inet_addr(str); + ok(addr == expected, "got addr %#08x, expected %#08x, i %u\n", addr, expected, i); + } +}
Ah, I see you did. I was expecting them to be added as part of the tests[] array, but that works too :-)