Commit 75be2284 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

ws2_32: Fix handling of NULL and empty hostname in getaddrinfo/GetAddrInfoW.

parent f87aee77
...@@ -4785,6 +4785,22 @@ static int convert_eai_u2w(int unixret) { ...@@ -4785,6 +4785,22 @@ static int convert_eai_u2w(int unixret) {
return 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.@) * getaddrinfo (WS2_32.@)
*/ */
...@@ -4794,17 +4810,19 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr ...@@ -4794,17 +4810,19 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr
struct addrinfo *unixaires = NULL; struct addrinfo *unixaires = NULL;
int result; int result;
struct addrinfo unixhints, *punixhints = NULL; struct addrinfo unixhints, *punixhints = NULL;
CHAR *node = NULL, *serv = NULL; char *hostname = NULL;
const char *node;
if (nodename) if (!nodename && !servname) return WSAHOST_NOT_FOUND;
if (!(node = strdup_lower(nodename))) return WSA_NOT_ENOUGH_MEMORY;
if (servname) { if (!nodename)
if (!(serv = strdup_lower(servname))) { node = "localhost";
HeapFree(GetProcessHeap(), 0, node); else if (!nodename[0])
return WSA_NOT_ENOUGH_MEMORY; node = hostname = get_hostname();
} else
} node = nodename;
if (!node) return WSA_NOT_ENOUGH_MEMORY;
if (hints) { if (hints) {
punixhints = &unixhints; punixhints = &unixhints;
...@@ -4826,12 +4844,10 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr ...@@ -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 */ /* 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); TRACE("%s, %s %p -> %p %d\n", debugstr_a(nodename), debugstr_a(servname), hints, res, result);
HeapFree(GetProcessHeap(), 0, hostname);
HeapFree(GetProcessHeap(), 0, node);
HeapFree(GetProcessHeap(), 0, serv);
if (!result) { if (!result) {
struct addrinfo *xuai = unixaires; struct addrinfo *xuai = unixaires;
...@@ -4991,15 +5007,15 @@ static struct WS_addrinfo *addrinfo_WtoA(const struct WS_addrinfoW *ai) ...@@ -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 WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hints, PADDRINFOW *res)
{ {
int ret, len; int ret, len;
char *nodenameA, *servnameA = NULL; char *nodenameA = NULL, *servnameA = NULL;
struct WS_addrinfo *resA, *hintsA = NULL; struct WS_addrinfo *resA, *hintsA = NULL;
if (!nodename) return WSAHOST_NOT_FOUND; if (nodename)
{
len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL); len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL);
if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY; if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY;
WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL);
}
if (servname) if (servname)
{ {
len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL); len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL);
......
...@@ -59,9 +59,11 @@ ...@@ -59,9 +59,11 @@
k.keepaliveinterval = interval; k.keepaliveinterval = interval;
/* Function pointers */ /* Function pointers */
static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW) = 0; static void (WINAPI *pfreeaddrinfo)(struct addrinfo *);
static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *) = 0; static int (WINAPI *pgetaddrinfo)(LPCSTR,LPCSTR,const struct addrinfo *,struct addrinfo **);
static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG) = 0; 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 ***************/ /**************** Structs and typedefs ***************/
...@@ -1002,6 +1004,8 @@ static void Init (void) ...@@ -1002,6 +1004,8 @@ static void Init (void)
WSADATA data; WSADATA data;
HMODULE hws2_32 = GetModuleHandle("ws2_32.dll"); 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"); pFreeAddrInfoW = (void *)GetProcAddress(hws2_32, "FreeAddrInfoW");
pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW"); pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW");
pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop"); pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop");
...@@ -4153,7 +4157,6 @@ static void test_GetAddrInfoW(void) ...@@ -4153,7 +4157,6 @@ static void test_GetAddrInfoW(void)
static const WCHAR empty[] = {0}; static const WCHAR empty[] = {0};
static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0}; static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0};
static const WCHAR zero[] = {'0',0}; static const WCHAR zero[] = {'0',0};
int ret; int ret;
ADDRINFOW *result, hint; ADDRINFOW *result, hint;
...@@ -4162,7 +4165,6 @@ static void test_GetAddrInfoW(void) ...@@ -4162,7 +4165,6 @@ static void test_GetAddrInfoW(void)
win_skip("GetAddrInfoW and/or FreeAddrInfoW not present\n"); win_skip("GetAddrInfoW and/or FreeAddrInfoW not present\n");
return; return;
} }
memset(&hint, 0, sizeof(ADDRINFOW)); memset(&hint, 0, sizeof(ADDRINFOW));
ret = pGetAddrInfoW(NULL, NULL, NULL, &result); ret = pGetAddrInfoW(NULL, NULL, NULL, &result);
...@@ -4170,44 +4172,107 @@ static void test_GetAddrInfoW(void) ...@@ -4170,44 +4172,107 @@ static void test_GetAddrInfoW(void)
result = NULL; result = NULL;
ret = pGetAddrInfoW(empty, NULL, NULL, &result); ret = pGetAddrInfoW(empty, NULL, NULL, &result);
todo_wine
{
ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
ok(result != NULL, "GetAddrInfoW failed\n"); ok(result != NULL, "GetAddrInfoW failed\n");
}
pFreeAddrInfoW(result); pFreeAddrInfoW(result);
result = NULL; result = NULL;
ret = pGetAddrInfoW(NULL, zero, NULL, &result); ret = pGetAddrInfoW(NULL, zero, NULL, &result);
todo_wine
{
ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
ok(result != NULL, "GetAddrInfoW failed\n"); ok(result != NULL, "GetAddrInfoW failed\n");
}
pFreeAddrInfoW(result); pFreeAddrInfoW(result);
result = NULL; result = NULL;
ret = pGetAddrInfoW(empty, zero, NULL, &result); ret = pGetAddrInfoW(empty, zero, NULL, &result);
todo_wine
{
ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
ok(result != NULL, "GetAddrInfoW failed\n"); ok(result != NULL, "GetAddrInfoW failed\n");
}
pFreeAddrInfoW(result); pFreeAddrInfoW(result);
result = NULL;
ret = pGetAddrInfoW(localhost, NULL, NULL, &result); ret = pGetAddrInfoW(localhost, NULL, NULL, &result);
ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
pFreeAddrInfoW(result); 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); ret = pGetAddrInfoW(localhost, port, NULL, &result);
ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
pFreeAddrInfoW(result); pFreeAddrInfoW(result);
result = NULL;
ret = pGetAddrInfoW(localhost, port, &hint, &result); ret = pGetAddrInfoW(localhost, port, &hint, &result);
ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
pFreeAddrInfoW(result); 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) static void test_ConnectEx(void)
{ {
SOCKET listener = INVALID_SOCKET; SOCKET listener = INVALID_SOCKET;
...@@ -5153,7 +5218,7 @@ START_TEST( sock ) ...@@ -5153,7 +5218,7 @@ START_TEST( sock )
test_ipv6only(); test_ipv6only();
test_GetAddrInfoW(); test_GetAddrInfoW();
test_getaddrinfo();
test_AcceptEx(); test_AcceptEx();
test_ConnectEx(); test_ConnectEx();
......
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