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) {
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;
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);
......
......@@ -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();
......
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