ws2_32: Avoid data corruption of WSAPROTOCOL_INFO in ws_protocol_info().

WS_EnterSingleProtocol[A/W]() fills WSAPROTOCOL_INFO with zeroes,
ovewriting what was already there, so in ws_protocol_info(),
populate the address family, socket type and protocol
only AFTER calling it.

Signed-off-by: Damjan Jovanovic <damjan.jov@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Damjan Jovanovic 2019-08-01 06:11:32 +02:00 committed by Alexandre Julliard
parent 0645e6c959
commit c722d819ea
2 changed files with 13 additions and 8 deletions

View File

@ -2328,6 +2328,9 @@ static INT WS_EnumProtocols( BOOL unicode, const INT *protocols, LPWSAPROTOCOL_I
static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size) static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size)
{ {
NTSTATUS status; NTSTATUS status;
int address_family;
int socket_type;
int protocol;
*size = unicode ? sizeof(WSAPROTOCOL_INFOW) : sizeof(WSAPROTOCOL_INFOA); *size = unicode ? sizeof(WSAPROTOCOL_INFOW) : sizeof(WSAPROTOCOL_INFOA);
memset(buffer, 0, *size); memset(buffer, 0, *size);
@ -2338,9 +2341,9 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i
status = wine_server_call( req ); status = wine_server_call( req );
if (!status) if (!status)
{ {
buffer->iAddressFamily = convert_af_u2w(reply->family); address_family = convert_af_u2w(reply->family);
buffer->iSocketType = convert_socktype_u2w(reply->type); socket_type = convert_socktype_u2w(reply->type);
buffer->iProtocol = convert_proto_u2w(reply->protocol); protocol = convert_proto_u2w(reply->protocol);
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
@ -2353,9 +2356,12 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i
} }
if (unicode) if (unicode)
WS_EnterSingleProtocolW( buffer->iProtocol, buffer); WS_EnterSingleProtocolW( protocol, buffer);
else else
WS_EnterSingleProtocolA( buffer->iProtocol, (WSAPROTOCOL_INFOA *)buffer); WS_EnterSingleProtocolA( protocol, (WSAPROTOCOL_INFOA *)buffer);
buffer->iAddressFamily = address_family;
buffer->iSocketType = socket_type;
buffer->iProtocol = protocol;
return TRUE; return TRUE;
} }

View File

@ -1668,9 +1668,8 @@ todo_wine
"SO_PROTOCOL_INFO[A/W] comparison failed\n"); "SO_PROTOCOL_INFO[A/W] comparison failed\n");
/* Remove IF when WSAEnumProtocols support IPV6 data */ /* Remove IF when WSAEnumProtocols support IPV6 data */
todo_wine_if (prottest[i].family == AF_INET6) ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n",
ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n", prottest[i].family, infoA.iAddressFamily);
prottest[i].family, infoA.iAddressFamily);
ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n", ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n",
prottest[i].type, infoA.iSocketType); prottest[i].type, infoA.iSocketType);
ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n", ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n",