ws2_32: Fix parameter validation order in getpeername.

This commit is contained in:
Andrew Nguyen 2010-02-03 01:18:40 -06:00 committed by Alexandre Julliard
parent 15998c2bdb
commit 1bcc3aa35c
2 changed files with 86 additions and 17 deletions

View File

@ -149,6 +149,7 @@
#include "iphlpapi.h"
#include "wine/server.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "wine/unicode.h"
#ifdef HAVE_IPX
@ -1796,13 +1797,6 @@ int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
TRACE("socket: %04lx, ptr %p, len %08x\n", s, name, *namelen);
/* Check if what we've received is valid. Should we use IsBadReadPtr? */
if( (name == NULL) || (namelen == NULL) )
{
SetLastError( WSAEFAULT );
return SOCKET_ERROR;
}
fd = get_sock_fd( s, 0, NULL );
res = SOCKET_ERROR;
@ -1811,19 +1805,18 @@ int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
union generic_unix_sockaddr uaddr;
unsigned int uaddrlen = sizeof(uaddr);
if (getpeername(fd, &uaddr.addr, &uaddrlen) != 0)
if (getpeername(fd, &uaddr.addr, &uaddrlen) == 0)
{
SetLastError(wsaErrno());
}
else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0)
{
/* The buffer was too small */
SetLastError(WSAEFAULT);
if (!name || !namelen)
SetLastError(WSAEFAULT);
else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0)
/* The buffer was too small */
SetLastError(WSAEFAULT);
else
res = 0;
}
else
{
res=0;
}
SetLastError(wsaErrno());
release_sock_fd( s, fd );
}
return res;

View File

@ -3257,6 +3257,81 @@ end:
closesocket(connector2);
}
static void test_getpeername(void)
{
SOCKET sock;
struct sockaddr_in sa, sa_out;
int sa_len;
const char buf[] = "hello world";
int ret;
/* Test the parameter validation order. */
ret = getpeername(INVALID_SOCKET, NULL, NULL);
ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
ok(WSAGetLastError() == WSAENOTSOCK,
"Expected WSAGetLastError() to return WSAENOTSOCK, got %d\n", WSAGetLastError());
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
if (sock == INVALID_SOCKET)
{
skip("Socket creation failed with %d\n", WSAGetLastError());
return;
}
ret = getpeername(sock, NULL, NULL);
ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
ok(WSAGetLastError() == WSAENOTCONN,
"Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(139);
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
/* sendto does not change a socket's connection state. */
ret = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&sa, sizeof(sa));
ok(ret != SOCKET_ERROR,
"Expected sendto to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
ret = getpeername(sock, NULL, NULL);
ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
ok(WSAGetLastError() == WSAENOTCONN,
"Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
ret = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
ok(ret == 0,
"Expected connect to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
ret = getpeername(sock, NULL, NULL);
ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
ok(WSAGetLastError() == WSAEFAULT,
"Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
/* Test crashes on Wine. */
if (0)
{
ret = getpeername(sock, (void*)0xdeadbeef, (void*)0xcafebabe);
ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
ok(WSAGetLastError() == WSAEFAULT,
"Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
}
sa_len = 0;
ret = getpeername(sock, (struct sockaddr*)&sa_out, &sa_len);
ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
ok(WSAGetLastError() == WSAEFAULT,
"Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
sa_len = sizeof(sa_out);
ret = getpeername(sock, (struct sockaddr*)&sa_out, &sa_len);
ok(ret == 0, "Expected getpeername to return 0, got %d\n", ret);
ok(!memcmp(&sa, &sa_out, sizeof(sa)),
"Expected the returned structure to be identical to the connect structure\n");
closesocket(sock);
}
/**************** Main program ***************/
START_TEST( sock )
@ -3294,6 +3369,7 @@ START_TEST( sock )
test_select();
test_accept();
test_getpeername();
test_getsockname();
test_inet_addr();
test_addr_to_print();