On Thu, 2021-10-14 at 18:17 +0300, Paul Gofman wrote:
Signed-off-by: Paul Gofman pgofman@codeweavers.com
The read completion callback may call WineHttpReadData(). Which may either run synchronously (if the data is available and recursion depth limit is not reached) or queued to thread pool. Fallout76 always proceeds with last WinHttpReadData of size 0 with recursion limit reached, and finished_reading() is racing between the (synchronous) call which has read the last portion of data and the queued WinHttpReadData called with zero size sometimes causing a crash in cache_connection which may be called with NULL connection in this case.
dlls/winhttp/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 2c064bb767b..a9c65d15fa8 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -1850,6 +1850,7 @@ static DWORD read_data( struct request *request, void *buffer, DWORD size, DWORD
done: TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, request->content_read, request->content_length );
- if (end_of_read_data( request )) finished_reading( request );
if (async) { if (!ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_READ_COMPLETE, buffer, bytes_read ); @@ -1863,7 +1864,6 @@ done: }
if (!ret && read) *read = bytes_read;
- if (end_of_read_data( request )) finished_reading( request );
return ret; }
This could use a test because it changes the order of notifications. When finished_reading() closes the connection WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION will now be sent before WINHTTP_CALLBACK_STATUS_READ_COMPLETE.