winhttp: Consider short read from netconn_recv() in receive_bytes().
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3a914ff488
commit
b5b066f62a
|
@ -3328,7 +3328,7 @@ DWORD WINAPI WinHttpWebSocketSend( HINTERNET hsocket, WINHTTP_WEB_SOCKET_BUFFER_
|
|||
return ret;
|
||||
}
|
||||
|
||||
static DWORD receive_bytes( struct socket *socket, char *buf, DWORD len, DWORD *ret_len )
|
||||
static DWORD receive_bytes( struct socket *socket, char *buf, DWORD len, DWORD *ret_len, BOOL read_full_buffer )
|
||||
{
|
||||
DWORD err, size = 0, needed = len;
|
||||
char *ptr = buf;
|
||||
|
@ -3342,8 +3342,17 @@ static DWORD receive_bytes( struct socket *socket, char *buf, DWORD len, DWORD *
|
|||
needed -= size;
|
||||
ptr += size;
|
||||
}
|
||||
if ((err = netconn_recv( socket->request->netconn, ptr, needed, 0, &received ))) return err;
|
||||
if ((*ret_len = size + received) != len) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE;
|
||||
while (size != len)
|
||||
{
|
||||
if ((err = netconn_recv( socket->request->netconn, ptr, needed, 0, &received ))) return err;
|
||||
if (!received) break;
|
||||
size += received;
|
||||
if (!read_full_buffer) break;
|
||||
needed -= received;
|
||||
ptr += received;
|
||||
}
|
||||
*ret_len = size;
|
||||
if (size != len && (read_full_buffer || !size)) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3368,7 +3377,7 @@ static DWORD receive_frame( struct socket *socket, DWORD *ret_len, enum socket_o
|
|||
DWORD ret, len, count;
|
||||
char hdr[2];
|
||||
|
||||
if ((ret = receive_bytes( socket, hdr, sizeof(hdr), &count ))) return ret;
|
||||
if ((ret = receive_bytes( socket, hdr, sizeof(hdr), &count, TRUE ))) return ret;
|
||||
if ((hdr[0] & RESERVED_BIT) || (hdr[1] & MASK_BIT) || !is_supported_opcode( hdr[0] & 0xf ))
|
||||
{
|
||||
return ERROR_WINHTTP_INVALID_SERVER_RESPONSE;
|
||||
|
@ -3380,13 +3389,13 @@ static DWORD receive_frame( struct socket *socket, DWORD *ret_len, enum socket_o
|
|||
if (len == 126)
|
||||
{
|
||||
USHORT len16;
|
||||
if ((ret = receive_bytes( socket, (char *)&len16, sizeof(len16), &count ))) return ret;
|
||||
if ((ret = receive_bytes( socket, (char *)&len16, sizeof(len16), &count, TRUE ))) return ret;
|
||||
len = RtlUshortByteSwap( len16 );
|
||||
}
|
||||
else if (len == 127)
|
||||
{
|
||||
ULONGLONG len64;
|
||||
if ((ret = receive_bytes( socket, (char *)&len64, sizeof(len64), &count ))) return ret;
|
||||
if ((ret = receive_bytes( socket, (char *)&len64, sizeof(len64), &count, TRUE ))) return ret;
|
||||
if ((len64 = RtlUlonglongByteSwap( len64 )) > ~0u) return ERROR_NOT_SUPPORTED;
|
||||
len = len64;
|
||||
}
|
||||
|
@ -3434,7 +3443,7 @@ static DWORD socket_drain( struct socket *socket )
|
|||
while (socket->read_size)
|
||||
{
|
||||
char buf[1024];
|
||||
if ((ret = receive_bytes( socket, buf, min(socket->read_size, sizeof(buf)), &count ))) return ret;
|
||||
if ((ret = receive_bytes( socket, buf, min(socket->read_size, sizeof(buf)), &count, TRUE ))) return ret;
|
||||
socket->read_size -= count;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -3496,9 +3505,12 @@ static DWORD socket_receive( struct socket *socket, void *buf, DWORD len, DWORD
|
|||
if (ret) break;
|
||||
}
|
||||
}
|
||||
if (!ret) ret = receive_bytes( socket, buf, min(len, socket->read_size), &count );
|
||||
if (!ret) ret = receive_bytes( socket, buf, min(len, socket->read_size), &count, FALSE );
|
||||
if (!ret)
|
||||
{
|
||||
if (count < socket->read_size)
|
||||
WARN("Short read.\n");
|
||||
|
||||
socket->read_size -= count;
|
||||
if (!async)
|
||||
{
|
||||
|
@ -3685,9 +3697,9 @@ static DWORD socket_close( struct socket *socket, USHORT status, const void *rea
|
|||
if (count)
|
||||
{
|
||||
DWORD reason_len = count - sizeof(socket->status);
|
||||
if ((ret = receive_bytes( socket, (char *)&socket->status, sizeof(socket->status), &count ))) goto done;
|
||||
if ((ret = receive_bytes( socket, (char *)&socket->status, sizeof(socket->status), &count, TRUE ))) goto done;
|
||||
socket->status = RtlUshortByteSwap( socket->status );
|
||||
if ((ret = receive_bytes( socket, socket->reason, reason_len, &socket->reason_len ))) goto done;
|
||||
if ((ret = receive_bytes( socket, socket->reason, reason_len, &socket->reason_len, TRUE ))) goto done;
|
||||
}
|
||||
socket->state = SOCKET_STATE_CLOSED;
|
||||
|
||||
|
|
Loading…
Reference in New Issue