The imported algorithm 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(a)codeweavers.com>
---
v2:
- add TRACE();
- formatting.
dlls/ws2_32/protocol.c | 51 +++++++++++++++++++++--
dlls/ws2_32/tests/protocol.c | 80 ++++++++++++++++++++++++++++++++++++
2 files changed, 127 insertions(+), 4 deletions(-)
diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c
index 0f56b1604d8..3194fff93cd 100644
--- a/dlls/ws2_32/protocol.c
+++ b/dlls/ws2_32/protocol.c
@@ -1834,17 +1834,60 @@ 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 || *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..847c147b4fd 100644
--- a/dlls/ws2_32/tests/protocol.c
+++ b/dlls/ws2_32/tests/protocol.c
@@ -674,6 +674,85 @@ 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},
+ };
+ unsigned int i;
+ u_long addr;
+
+ 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();
+ }
+}
+
static void test_inet_pton(void)
{
static const struct
@@ -2871,6 +2950,7 @@ START_TEST( protocol )
test_WSALookupService();
test_inet_ntoa();
+ test_inet_addr();
test_inet_pton();
test_addr_to_print();
test_WSAAddressToString();
--
2.35.1