Commit 7d9a4392 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

wininet: Don't return available data sizes larger than the read buffer.

Based on patch by Hans Leidekker. Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent d6d0d964
...@@ -2621,7 +2621,16 @@ static DWORD refill_read_buffer(http_request_t *req, blocking_mode_t blocking_mo ...@@ -2621,7 +2621,16 @@ static DWORD refill_read_buffer(http_request_t *req, blocking_mode_t blocking_mo
/* return the size of data available to be read immediately (the read section must be held) */ /* return the size of data available to be read immediately (the read section must be held) */
static DWORD get_avail_data( http_request_t *req ) static DWORD get_avail_data( http_request_t *req )
{ {
return req->read_size + req->data_stream->vtbl->get_avail_data(req->data_stream, req); DWORD avail = req->read_size;
/*
* Different Windows versions have different limits of returned data, but all
* of them return no more than centrain amount. We use READ_BUFFER_SIZE as a limit.
*/
if(avail < READ_BUFFER_SIZE)
avail += req->data_stream->vtbl->get_avail_data(req->data_stream, req);
return min(avail, READ_BUFFER_SIZE);
} }
static DWORD netconn_get_avail_data(data_stream_t *stream, http_request_t *req) static DWORD netconn_get_avail_data(data_stream_t *stream, http_request_t *req)
......
...@@ -4622,11 +4622,10 @@ static void open_read_test_request(int port, test_request_t *req, const char *re ...@@ -4622,11 +4622,10 @@ static void open_read_test_request(int port, test_request_t *req, const char *re
CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE); CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
} }
#define readex_expect_sync_data(a,b,c,d,e) _readex_expect_sync_data(__LINE__,a,b,c,d,e) #define readex_expect_sync_data_len(a,b,c,d,e,f) _readex_expect_sync_data_len(__LINE__,a,b,c,d,e,f)
static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf, static void _readex_expect_sync_data_len(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
DWORD buf_size, const char *exdata) DWORD buf_size, const char *exdata, DWORD len)
{ {
DWORD len = strlen(exdata);
BOOL ret; BOOL ret;
SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE); SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
...@@ -4636,12 +4635,19 @@ static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags, ...@@ -4636,12 +4635,19 @@ static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags,
ret = InternetReadFileExW(req, buf, flags, 0xdeadbeef); ret = InternetReadFileExW(req, buf, flags, 0xdeadbeef);
ok_(__FILE__,line)(ret, "InternetReadFileExW failed: %u\n", GetLastError()); ok_(__FILE__,line)(ret, "InternetReadFileExW failed: %u\n", GetLastError());
ok_(__FILE__,line)(buf->dwBufferLength == len, "dwBufferLength = %u, expected %u\n", buf->dwBufferLength, len); ok_(__FILE__,line)(buf->dwBufferLength == len, "dwBufferLength = %u, expected %u\n", buf->dwBufferLength, len);
if(len) if(len && exdata)
ok_(__FILE__,line)(!memcmp(buf->lpvBuffer, exdata, len), "Unexpected data\n"); ok_(__FILE__,line)(!memcmp(buf->lpvBuffer, exdata, len), "Unexpected data\n");
CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE); CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
} }
#define readex_expect_sync_data(a,b,c,d,e) _readex_expect_sync_data(__LINE__,a,b,c,d,e)
static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
DWORD buf_size, const char *exdata)
{
_readex_expect_sync_data_len(line, req, flags, buf, buf_size, exdata, strlen(exdata));
}
static void send_response_and_wait(const char *response, BOOL close_connection, INTERNET_BUFFERSW *buf) static void send_response_and_wait(const char *response, BOOL close_connection, INTERNET_BUFFERSW *buf)
{ {
DWORD orig_size = buf->dwBufferLength; DWORD orig_size = buf->dwBufferLength;
...@@ -4666,6 +4672,17 @@ static void send_response_and_wait(const char *response, BOOL close_connection, ...@@ -4666,6 +4672,17 @@ static void send_response_and_wait(const char *response, BOOL close_connection,
ok(!*(int*)buf->lpvBuffer, "buffer data changed\n"); ok(!*(int*)buf->lpvBuffer, "buffer data changed\n");
} }
static void send_response_len_and_wait(unsigned len, BOOL close_connection, INTERNET_BUFFERSW *buf)
{
char *response;
response = HeapAlloc(GetProcessHeap(), 0, len+1);
memset(response, 'x', len);
response[len] = 0;
send_response_and_wait(response, close_connection, buf);
HeapFree(GetProcessHeap(), 0, response);
}
static void readex_expect_async(HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf, DWORD buf_size) static void readex_expect_async(HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf, DWORD buf_size)
{ {
BOOL ret; BOOL ret;
...@@ -4678,11 +4695,26 @@ static void readex_expect_async(HINTERNET req, DWORD flags, INTERNET_BUFFERSW *b ...@@ -4678,11 +4695,26 @@ static void readex_expect_async(HINTERNET req, DWORD flags, INTERNET_BUFFERSW *b
ok(!*(int*)buf->lpvBuffer, "buffer data changed\n"); ok(!*(int*)buf->lpvBuffer, "buffer data changed\n");
} }
#define expect_data_available(a,b) _expect_data_available(__LINE__,a,b)
static DWORD _expect_data_available(unsigned line, HINTERNET req, int exsize)
{
DWORD size = 0;
BOOL res;
res = InternetQueryDataAvailable(req, &size, 0, 0);
ok_(__FILE__,line)(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
if(exsize != -1)
ok_(__FILE__,line)(size == exsize, "size = %u, expected %u\n", size, exsize);
return size;
}
static void test_http_read(int port) static void test_http_read(int port)
{ {
INTERNET_BUFFERSW ib; INTERNET_BUFFERSW ib;
test_request_t req; test_request_t req;
char buf[4096]; char buf[24000];
DWORD avail;
if(!is_ie7plus) if(!is_ie7plus)
return; return;
...@@ -4759,6 +4791,27 @@ static void test_http_read(int port) ...@@ -4759,6 +4791,27 @@ static void test_http_read(int port)
close_async_handle(req.session, hCompleteEvent, 2); close_async_handle(req.session, hCompleteEvent, 2);
trace("Testing InternetQueryDataAvailable...\n");
open_read_test_request(port, &req,
"HTTP/1.1 200 OK\r\n"
"Server: winetest\r\n"
"\r\n"
"123");
expect_data_available(req.request, 3);
readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123");
readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf));
send_response_len_and_wait(20000, TRUE, &ib);
avail = expect_data_available(req.request, -1);
ok(avail < 17000, "avail = %u\n", avail);
SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
close_async_handle(req.session, hCompleteEvent, 2);
todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
CloseHandle(hCompleteEvent); CloseHandle(hCompleteEvent);
CloseHandle(conn_wait_event); CloseHandle(conn_wait_event);
CloseHandle(server_req_rec_event); CloseHandle(server_req_rec_event);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment