https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7ca1d0e161cdbff7b6941…
commit 7ca1d0e161cdbff7b694100f73d642e704faf3af
Author:     Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sun Mar 19 09:26:24 2023 -0400
Commit:     Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Sun Mar 19 10:02:16 2023 -0400
    [WS2_32_APITEST] Add a test for recv overread. CORE-18328
---
 modules/rostests/apitests/ws2_32/recv.c | 144 +++++++++++++++++++++++++++++++-
 1 file changed, 140 insertions(+), 4 deletions(-)
diff --git a/modules/rostests/apitests/ws2_32/recv.c
b/modules/rostests/apitests/ws2_32/recv.c
index 9721280b7a3..c64fdbbea1d 100644
--- a/modules/rostests/apitests/ws2_32/recv.c
+++ b/modules/rostests/apitests/ws2_32/recv.c
@@ -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(a)reactos.org)
+ *              Copyright 2010 Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ *              Copyright 2012 Cameron Gutman (cameron.gutman(a)reactos.org)
+ *              Copyright 2023 Thomas Faber (thomas.faber(a)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();
 }