[WS2_32_APITEST] Add a test for recv overread. CORE-18328
authorThomas Faber <thomas.faber@reactos.org>
Sun, 19 Mar 2023 13:26:24 +0000 (09:26 -0400)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 19 Mar 2023 14:02:16 +0000 (10:02 -0400)
modules/rostests/apitests/ws2_32/recv.c

index 9721280..c64fdbb 100644 (file)
@@ -1,8 +1,11 @@
 /*
- * PROJECT:         ReactOS api tests
- * LICENSE:         GPL - See COPYING in the top level directory
- * PURPOSE:         Test for recv
- * PROGRAMMERS:     Colin Finck
+ * PROJECT:     ReactOS API Tests
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * PURPOSE:     Test for recv
+ * COPYRIGHT:   Copyright 2008 Colin Finck (colin@reactos.org)
+ *              Copyright 2010 Timo Kreuzer (timo.kreuzer@reactos.org)
+ *              Copyright 2012 Cameron Gutman (cameron.gutman@reactos.org)
+ *              Copyright 2023 Thomas Faber (thomas.faber@reactos.org)
  */
 
 #include "ws2_32.h"
@@ -118,8 +121,141 @@ int Test_recv()
     return 1;
 }
 
+static void Test_Overread(void)
+{
+    WSADATA wsaData;
+    SOCKET ListeningSocket = INVALID_SOCKET;
+    SOCKET ServerSocket = INVALID_SOCKET;
+    SOCKET ClientSocket = INVALID_SOCKET;
+    SOCKADDR_IN address;
+    char buffer[32];
+    int ret;
+    int error;
+    int len;
+
+    ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
+    if (ret != 0)
+    {
+        skip("Failed to initialize WinSock, error %d\n", ret);
+        goto Exit;
+    }
+
+    ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (ListeningSocket == INVALID_SOCKET || ClientSocket == INVALID_SOCKET)
+    {
+        skip("Failed to create sockets, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+
+    /* Bind to random port */
+    address.sin_family = AF_INET;
+    address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    address.sin_port = 0;
+    ret = bind(ListeningSocket, (SOCKADDR *)&address, sizeof(address));
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to bind socket, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+
+    ret = listen(ListeningSocket, 1);
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to listen on socket, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+
+    len = sizeof(address);
+    ret = getsockname(ListeningSocket, (SOCKADDR *)&address, &len);
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to get listening port on socket, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+    ok(len == sizeof(address), "getsocketname length %d\n", len);
+
+    ret = connect(ClientSocket, (SOCKADDR *)&address, sizeof(address));
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to connect to socket, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+
+    ServerSocket = accept(ListeningSocket, NULL, NULL);
+    if (ServerSocket == INVALID_SOCKET)
+    {
+        skip("Failed to accept client socket, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+
+    ret = send(ServerSocket, "blah", 4, 0);
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to send to socket, error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+
+    ret = closesocket(ServerSocket);
+    ServerSocket = INVALID_SOCKET;
+    ok(ret == 0, "Failed to close socket with %d\n", WSAGetLastError());
+
+    memset(buffer, 0, sizeof(buffer));
+    ret = recv(ClientSocket, buffer, sizeof(buffer), 0);
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to receive from socket (1), error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+    error = WSAGetLastError();
+    ok(ret == 4, "recv (1) returned %d\n", ret);
+    ok(error == NO_ERROR, "recv (1) returned error %d\n", ret);
+    buffer[4] = 0;
+    ok(!strcmp(buffer, "blah"), "recv (1) returned data: %s\n", buffer);
+
+    ret = recv(ClientSocket, buffer, sizeof(buffer), 0);
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to receive from socket (2), error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+    error = WSAGetLastError();
+    ok(ret == 0, "recv (2) returned %d\n", ret);
+    ok(error == NO_ERROR, "recv (2) returned error %d\n", ret);
+
+    ret = recv(ClientSocket, buffer, sizeof(buffer), 0);
+    if (ret == SOCKET_ERROR)
+    {
+        skip("Failed to receive from socket (3), error %d\n", WSAGetLastError());
+        goto Exit;
+    }
+    error = WSAGetLastError();
+    ok(ret == 0, "recv (3) returned %d\n", ret);
+    ok(error == NO_ERROR, "recv (3) returned error %d\n", ret);
+
+Exit:
+    if (ListeningSocket != INVALID_SOCKET)
+    {
+        ret = closesocket(ListeningSocket);
+        ok(ret == 0, "closesocket (1) failed with %d\n", WSAGetLastError());
+    }
+    if (ClientSocket != INVALID_SOCKET)
+    {
+        ret = closesocket(ClientSocket);
+        ok(ret == 0, "closesocket (2) failed with %d\n", WSAGetLastError());
+    }
+    if (ServerSocket != INVALID_SOCKET)
+    {
+        ret = closesocket(ServerSocket);
+        ok(ret == 0, "closesocket (3) failed with %d\n", WSAGetLastError());
+    }
+    ret = WSACleanup();
+    ok(ret == 0, "WSACleanup failed with %d\n", WSAGetLastError());
+}
+
 START_TEST(recv)
 {
     Test_recv();
+    Test_Overread();
 }