Module: wine Branch: master Commit: 94f431e3eebe44a88752be72a795baf33e55a213 URL: http://source.winehq.org/git/wine.git/?a=commit;h=94f431e3eebe44a88752be72a7...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Sep 14 12:04:39 2011 +0200
ws2_32: Avoid a crash in WS2_recv_base.
---
dlls/ws2_32/socket.c | 3 +- dlls/ws2_32/tests/sock.c | 65 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index b6d17ff..f0313fc 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -5720,8 +5720,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, goto error; } } - else - *lpNumberOfBytesRecvd = n; + else if (lpNumberOfBytesRecvd) *lpNumberOfBytesRecvd = n;
if ((lpOverlapped || lpCompletionRoutine) && !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 326b77d..b358250 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4031,18 +4031,37 @@ static void test_WSASendTo(void) "a successful call to WSASendTo()\n"); }
+static DWORD WINAPI recv_thread(LPVOID arg) +{ + SOCKET sock = *(SOCKET *)arg; + char buffer[32]; + WSABUF wsa; + WSAOVERLAPPED ov; + DWORD flags = 0; + + wsa.buf = buffer; + wsa.len = sizeof(buffer); + ov.hEvent = WSACreateEvent(); + WSARecv(sock, &wsa, 1, NULL, &flags, &ov, NULL); + + WaitForSingleObject(ov.hEvent, 1000); + WSACloseEvent(ov.hEvent); + return 0; +} + static void test_WSARecv(void) { - SOCKET src, dest; + SOCKET src, dest, server = INVALID_SOCKET; char buf[20]; WSABUF bufs; WSAOVERLAPPED ov; - DWORD bytesReturned; - DWORD flags; + DWORD bytesReturned, flags, id; struct linger ling; - int iret; + struct sockaddr_in addr; + int iret, len; DWORD dwret; BOOL bret; + HANDLE thread;
memset(&ov, 0, sizeof(ov));
@@ -4067,6 +4086,9 @@ static void test_WSARecv(void) iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling)); ok(!iret, "Failed to set linger %d\n", GetLastError());
+ iret = WSARecv(dest, &bufs, 1, NULL, &flags, &ov, NULL); + ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError()); + iret = WSARecv(dest, &bufs, 1, &bytesReturned, &flags, &ov, NULL); ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
@@ -4081,7 +4103,42 @@ static void test_WSARecv(void) "Did not get disconnect event: %d, error %d\n", bret, GetLastError()); ok(bytesReturned == 0, "Bytes received is %d\n", bytesReturned);
+ src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); + ok(src != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError()); + if (src == INVALID_SOCKET) goto end; + + server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); + ok(server != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError()); + if (server == INVALID_SOCKET) goto end; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + iret = bind(server, (struct sockaddr *)&addr, sizeof(addr)); + if (iret) goto end; + + len = sizeof(addr); + iret = getsockname(server, (struct sockaddr *)&addr, &len); + if (iret) goto end; + + iret = listen(server, 1); + if (iret) goto end; + + iret = connect(src, (struct sockaddr *)&addr, sizeof(addr)); + if (iret) goto end; + + len = sizeof(addr); + dest = accept(server, (struct sockaddr *)&addr, &len); + ok(dest != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError()); + if (dest == INVALID_SOCKET) goto end; + + send(src, "test message", sizeof("test message"), 0); + thread = CreateThread(NULL, 0, recv_thread, &dest, 0, &id); + CloseHandle(thread); + end: + if (server != INVALID_SOCKET) + closesocket(server); if (dest != INVALID_SOCKET) closesocket(dest); if (src != INVALID_SOCKET)