ws2_32: Fix handling of NULL and empty hostname in getaddrinfo/GetAddrInfoW.
This commit is contained in:
parent
f87aee778d
commit
75be2284e1
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue