Module: wine Branch: master Commit: 75be2284e13d327d93a9665eb32cd901cbed7234 URL: http://source.winehq.org/git/wine.git/?a=commit;h=75be2284e13d327d93a9665eb3...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Nov 15 11:38:20 2011 +0100
ws2_32: Fix handling of NULL and empty hostname in getaddrinfo/GetAddrInfoW.
---
dlls/ws2_32/socket.c | 56 +++++++++++++++++---------- dlls/ws2_32/tests/sock.c | 95 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 35 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 00a15b6..fe645c1 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -4785,6 +4785,22 @@ static int convert_eai_u2w(int unixret) { return unixret; }
+static char *get_hostname(void) +{ + char *ret; + DWORD size = 0; + + GetComputerNameExA( ComputerNamePhysicalDnsHostname, NULL, &size ); + if (GetLastError() != ERROR_MORE_DATA) return NULL; + if (!(ret = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL; + if (!GetComputerNameExA( ComputerNamePhysicalDnsHostname, ret, &size )) + { + HeapFree( GetProcessHeap(), 0, ret ); + return NULL; + } + return ret; +} + /*********************************************************************** * getaddrinfo (WS2_32.@) */ @@ -4794,17 +4810,19 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr struct addrinfo *unixaires = NULL; int result; struct addrinfo unixhints, *punixhints = NULL; - CHAR *node = NULL, *serv = NULL; + char *hostname = NULL; + const char *node;
- if (nodename) - if (!(node = strdup_lower(nodename))) return WSA_NOT_ENOUGH_MEMORY; + if (!nodename && !servname) return WSAHOST_NOT_FOUND;
- if (servname) { - if (!(serv = strdup_lower(servname))) { - HeapFree(GetProcessHeap(), 0, node); - return WSA_NOT_ENOUGH_MEMORY; - } - } + if (!nodename) + node = "localhost"; + else if (!nodename[0]) + node = hostname = get_hostname(); + else + node = nodename; + + if (!node) return WSA_NOT_ENOUGH_MEMORY;
if (hints) { punixhints = &unixhints; @@ -4826,12 +4844,10 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr }
/* getaddrinfo(3) is thread safe, no need to wrap in CS */ - result = getaddrinfo(nodename, servname, punixhints, &unixaires); + result = getaddrinfo(node, servname, punixhints, &unixaires);
TRACE("%s, %s %p -> %p %d\n", debugstr_a(nodename), debugstr_a(servname), hints, res, result); - - HeapFree(GetProcessHeap(), 0, node); - HeapFree(GetProcessHeap(), 0, serv); + HeapFree(GetProcessHeap(), 0, hostname);
if (!result) { struct addrinfo *xuai = unixaires; @@ -4991,15 +5007,15 @@ static struct WS_addrinfo *addrinfo_WtoA(const struct WS_addrinfoW *ai) int WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hints, PADDRINFOW *res) { int ret, len; - char *nodenameA, *servnameA = NULL; + char *nodenameA = NULL, *servnameA = NULL; struct WS_addrinfo *resA, *hintsA = NULL;
- if (!nodename) return WSAHOST_NOT_FOUND; - - len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL); - if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY; - WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL); - + if (nodename) + { + len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL); + if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY; + WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL); + } if (servname) { len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 237bc86..7b5dde8 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -59,9 +59,11 @@ k.keepaliveinterval = interval;
/* Function pointers */ -static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW) = 0; -static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *) = 0; -static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG) = 0; +static void (WINAPI *pfreeaddrinfo)(struct addrinfo *); +static int (WINAPI *pgetaddrinfo)(LPCSTR,LPCSTR,const struct addrinfo *,struct addrinfo **); +static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW); +static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *); +static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG);
/**************** Structs and typedefs ***************/
@@ -1002,6 +1004,8 @@ static void Init (void) WSADATA data; HMODULE hws2_32 = GetModuleHandle("ws2_32.dll");
+ pfreeaddrinfo = (void *)GetProcAddress(hws2_32, "freeaddrinfo"); + pgetaddrinfo = (void *)GetProcAddress(hws2_32, "getaddrinfo"); pFreeAddrInfoW = (void *)GetProcAddress(hws2_32, "FreeAddrInfoW"); pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW"); pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop"); @@ -4153,7 +4157,6 @@ static void test_GetAddrInfoW(void) static const WCHAR empty[] = {0}; static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0}; static const WCHAR zero[] = {'0',0}; - int ret; ADDRINFOW *result, hint;
@@ -4162,7 +4165,6 @@ static void test_GetAddrInfoW(void) win_skip("GetAddrInfoW and/or FreeAddrInfoW not present\n"); return; } - memset(&hint, 0, sizeof(ADDRINFOW));
ret = pGetAddrInfoW(NULL, NULL, NULL, &result); @@ -4170,44 +4172,107 @@ static void test_GetAddrInfoW(void)
result = NULL; ret = pGetAddrInfoW(empty, NULL, NULL, &result); - todo_wine - { ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(result != NULL, "GetAddrInfoW failed\n"); - } pFreeAddrInfoW(result);
result = NULL; ret = pGetAddrInfoW(NULL, zero, NULL, &result); - todo_wine - { ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(result != NULL, "GetAddrInfoW failed\n"); - } pFreeAddrInfoW(result);
result = NULL; ret = pGetAddrInfoW(empty, zero, NULL, &result); - todo_wine - { ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(result != NULL, "GetAddrInfoW failed\n"); - } pFreeAddrInfoW(result);
+ result = NULL; ret = pGetAddrInfoW(localhost, NULL, NULL, &result); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); pFreeAddrInfoW(result);
+ result = NULL; + ret = pGetAddrInfoW(localhost, empty, NULL, &result); + ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); + pFreeAddrInfoW(result); + + result = NULL; + ret = pGetAddrInfoW(localhost, zero, NULL, &result); + ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); + pFreeAddrInfoW(result); + + result = NULL; ret = pGetAddrInfoW(localhost, port, NULL, &result); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); pFreeAddrInfoW(result);
+ result = NULL; ret = pGetAddrInfoW(localhost, port, &hint, &result); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); pFreeAddrInfoW(result); }
+static void test_getaddrinfo(void) +{ + int ret; + ADDRINFOA *result, hint; + + if (!pgetaddrinfo || !pfreeaddrinfo) + { + win_skip("getaddrinfo and/or freeaddrinfo not present\n"); + return; + } + memset(&hint, 0, sizeof(ADDRINFOA)); + + ret = pgetaddrinfo(NULL, NULL, NULL, &result); + ok(ret == WSAHOST_NOT_FOUND, "got %d expected WSAHOST_NOT_FOUND\n", ret); + + result = NULL; + ret = pgetaddrinfo("", NULL, NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + ok(result != NULL, "getaddrinfo failed\n"); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo(NULL, "0", NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + ok(result != NULL, "getaddrinfo failed\n"); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo("", "0", NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + ok(result != NULL, "getaddrinfo failed\n"); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo("localhost", NULL, NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo("localhost", "", NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo("localhost", "0", NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo("localhost", "80", NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + pfreeaddrinfo(result); + + result = NULL; + ret = pgetaddrinfo("localhost", "80", &hint, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + pfreeaddrinfo(result); +} + static void test_ConnectEx(void) { SOCKET listener = INVALID_SOCKET; @@ -5153,7 +5218,7 @@ START_TEST( sock )
test_ipv6only(); test_GetAddrInfoW(); - + test_getaddrinfo(); test_AcceptEx(); test_ConnectEx();