[PATCH 5/7] ws2_32/tests: Add tests for setting and getting socket options with shorter length.
Paul Gofman
pgofman at codeweavers.com
Sat Mar 5 13:04:07 CST 2022
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/ws2_32/tests/sock.c | 138 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 136 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 6b6267dc153..6e492ffbb61 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -1155,15 +1155,38 @@ static const LINGER linger_testvals[] = {
static void test_set_getsockopt(void)
{
+ static struct
+ {
+ int af;
+ int type;
+ int level;
+ int optname;
+ BOOL accepts_short_len;
+ unsigned int sizes[3];
+ DWORD values[3];
+ }
+ test_optsize[] =
+ {
+ {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}},
+ {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}},
+ {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_LOOP, TRUE, {1, 1, 4}},
+ {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_TTL, TRUE, {1, 1, 4}},
+ {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TOS, TRUE, {1, 1, 4}},
+ {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TTL, TRUE, {1, 1, 4}},
+ };
SOCKET s, s2;
- int i, err, lasterr;
+ int i, j, err, lasterr;
int timeout;
LINGER lingval;
int size;
WSAPROTOCOL_INFOA infoA;
WSAPROTOCOL_INFOW infoW;
char providername[WSAPROTOCOL_LEN + 1];
- DWORD value;
+ DWORD expected_last_error, expected_value;
+ int expected_err, expected_size;
+ DWORD value, save_value;
+ UINT64 value64;
+
struct _prottest
{
int family, type, proto;
@@ -1375,6 +1398,117 @@ static void test_set_getsockopt(void)
err, WSAGetLastError());
closesocket(s);
+
+ /* Test option length. */
+ for (i = 0; i < ARRAY_SIZE(test_optsize); ++i)
+ {
+ winetest_push_context("i %u, level %d, optname %d",
+ i, test_optsize[i].level, test_optsize[i].optname);
+
+ s2 = socket( test_optsize[i].af, test_optsize[i].type, 0 );
+ ok(s2 != INVALID_SOCKET, "socket() failed error %d\n", WSAGetLastError());
+
+ size = sizeof(save_value);
+ err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&save_value, &size);
+ ok(!err, "Unexpected getsockopt result %d.\n", err);
+
+ value64 = 0xffffffff00000001;
+ err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char *)&value64, sizeof(value64));
+ ok(!err, "Unexpected setsockopt result %d.\n", err);
+ ok(!WSAGetLastError(), "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
+
+ size = sizeof(value64);
+ err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value64, &size);
+ ok(!err, "Unexpected getsockopt result %d.\n", err);
+ ok(size == test_optsize[i].sizes[2], "Got unexpected size %d.\n", size);
+ /* The behaviour regarding filling the high dword is different between options without the obvious
+ * pattern, it is either left untouched (more often) or zeroed. Wine doesn't touch the high dword. */
+
+ if (test_optsize[i].sizes[2] == 1 || test_optsize[i].level != SOL_SOCKET)
+ {
+ expected_err = -1;
+ expected_last_error = WSAENOBUFS;
+ }
+ else
+ {
+ expected_err = 0;
+ expected_last_error = 0;
+ }
+
+ value = 1;
+ err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char *)&value, -1);
+ ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
+ /* Broken between Win7 and Win10 21H1. */
+ ok(WSAGetLastError() == expected_last_error || broken(expected_last_error && WSAGetLastError() == WSAEFAULT),
+ "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
+
+ size = -1;
+ value = 0xdeadbeef;
+ err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
+ if (test_optsize[i].optname == SO_OPENTYPE)
+ {
+ ok(!err, "Unexpected getsockopt result %d.\n", err);
+ ok(!WSAGetLastError(), "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
+ }
+ else
+ {
+ ok(err == -1, "Unexpected getsockopt result %d.\n", err);
+ ok(WSAGetLastError() == WSAEFAULT, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
+ }
+ ok(size == (test_optsize[i].optname == SO_OPENTYPE ? 4 : -1), "Got unexpected size %d.\n", size);
+
+ winetest_pop_context();
+
+ for (j = 0; j < ARRAY_SIZE(test_optsize[i].sizes); ++j)
+ {
+ size = 1 << j;
+ winetest_push_context("i %u, level %d, optname %d, len %u",
+ i, test_optsize[i].level, test_optsize[i].optname, size);
+
+ value = 1;
+ if (test_optsize[i].values[j])
+ expected_value = test_optsize[i].values[j];
+ else
+ expected_value = 0xdeadbeef;
+
+ if (test_optsize[i].accepts_short_len || size == 4)
+ {
+ expected_err = 0;
+ expected_last_error = 0;
+ expected_size = test_optsize[i].sizes[j];
+
+ if (!test_optsize[i].values[j])
+ memcpy(&expected_value, &value, expected_size);
+ }
+ else
+ {
+ expected_err = -1;
+ expected_last_error = WSAEFAULT;
+ expected_size = test_optsize[i].sizes[j];
+ }
+
+ SetLastError(0xdeadbeef);
+ err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, size);
+ ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
+ ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
+
+ value = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
+ ok(err == expected_err, "Unexpected getsockopt result %d.\n", err);
+ ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
+ ok(value == expected_value, "Got unexpected value %#x, expected %#x.\n", value, expected_value);
+ ok(size == expected_size, "Got unexpected size %d, expected %d.\n", size, expected_size);
+
+ winetest_pop_context();
+ }
+
+ err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname,
+ (char*)&save_value, sizeof(save_value));
+ ok(!err, "Unexpected getsockopt result %d.\n", err);
+ closesocket(s2);
+ }
+
/* Test with the closed socket */
SetLastError(0xdeadbeef);
size = sizeof(i);
--
2.35.1
More information about the wine-devel
mailing list