From 7c037c82c8c56539dd03e00628e27e4525b66483 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 6 Jan 2022 19:30:37 +0100 Subject: [PATCH] urlmon: Don't allow direct sink callbacks when reporting data. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52286 Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/urlmon/bindprot.c | 49 +++++++++++++++++++++------------- dlls/urlmon/tests/protocol.c | 51 +++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 30 deletions(-) diff --git a/dlls/urlmon/bindprot.c b/dlls/urlmon/bindprot.c index 2e58884b199..1cf1adcb8f6 100644 --- a/dlls/urlmon/bindprot.c +++ b/dlls/urlmon/bindprot.c @@ -915,34 +915,20 @@ static HRESULT WINAPI ProtocolSinkHandler_ReportProgress(IInternetProtocolSink * return S_OK; } -static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *iface, - DWORD bscf, ULONG progress, ULONG progress_max) +static HRESULT report_data(BindProtocol *This) { - BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface); - - TRACE("(%p)->(%x %u %u)\n", This, bscf, progress, progress_max); - - This->bscf = bscf; - This->progress = progress; - This->progress_max = progress_max; - - if(!This->protocol_sink) - return S_OK; + DWORD bscf = This->bscf; + HRESULT hres; if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) { BYTE buf[BUFFER_SIZE]; DWORD read = 0; LPWSTR mime; - HRESULT hres; do { read = 0; - if(is_apartment_thread(This)) - This->continue_call++; hres = IInternetProtocol_Read(This->protocol, buf, sizeof(buf)-This->buf_size, &read); - if(is_apartment_thread(This)) - This->continue_call--; if(FAILED(hres) && hres != E_PENDING) return hres; @@ -995,7 +981,34 @@ static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *ifac if(!This->protocol_sink) return S_OK; - return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max); + return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, This->progress, This->progress_max); +} + +static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *iface, + DWORD bscf, ULONG progress, ULONG progress_max) +{ + BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface); + HRESULT hres; + + TRACE("(%p)->(%x %u %u)\n", This, bscf, progress, progress_max); + + This->bscf = bscf; + This->progress = progress; + This->progress_max = progress_max; + + if(!This->protocol_sink) + return S_OK; + + if(is_apartment_thread(This)) + This->continue_call++; + + hres = report_data(This); + + if(is_apartment_thread(This)) { + This->continue_call--; + process_tasks(This); + } + return hres; } static HRESULT handle_redirect(BindProtocol *This, const WCHAR *url) diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c index a5406121585..b997be7fa01 100644 --- a/dlls/urlmon/tests/protocol.c +++ b/dlls/urlmon/tests/protocol.c @@ -161,7 +161,7 @@ static DWORD prot_read, filter_state, http_post_test, thread_id; static BOOL security_problem, test_async_req, impl_protex; static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort; static BOOL empty_file, no_mime, bind_from_cache, file_with_hash, reuse_protocol_thread; -static BOOL no_aggregation; +static BOOL no_aggregation, result_from_lock; enum { STATE_CONNECTING, @@ -1168,6 +1168,16 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR } } + if(result_from_lock) { + SET_EXPECT(LockRequest); + hres = IInternetProtocol_LockRequest(binding_protocol, 0); + ok(hres == S_OK, "LockRequest failed: %08x\n", hres); + CHECK_CALLED(LockRequest); + + /* ReportResult is called before ReportData returns */ + SET_EXPECT(ReportResult); + } + rec_depth--; return S_OK; } @@ -1911,6 +1921,12 @@ static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo else CHECK_CALLED(ReportData); + if(result_from_lock) { + /* set in ProtocolSink_ReportData */ + CHECK_CALLED(ReportResult); + return; + } + if(tested_protocol == ITS_TEST) { SET_EXPECT(ReportData); hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL); @@ -2202,6 +2218,11 @@ static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD { CHECK_EXPECT(LockRequest); ok(dwOptions == 0, "dwOptions=%x\n", dwOptions); + if(result_from_lock) { + HRESULT hres; + hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL); + ok(hres == S_OK, "ReportResult failed: %08x, expected E_FAIL\n", hres); + } return S_OK; } @@ -2688,6 +2709,7 @@ static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl }; #define TEST_NOMIME 0x2000 #define TEST_FROMCACHE 0x4000 #define TEST_DISABLEAUTOREDIRECT 0x8000 +#define TEST_RESULTFROMLOCK 0x10000 static void register_filter(BOOL do_register) { @@ -2744,6 +2766,7 @@ static void init_test(int prot, DWORD flags) impl_protex = (flags & TEST_IMPLPROTEX) != 0; empty_file = (flags & TEST_EMPTY) != 0; bind_from_cache = (flags & TEST_FROMCACHE) != 0; + result_from_lock = (flags & TEST_RESULTFROMLOCK) != 0; file_with_hash = FALSE; security_problem = FALSE; reuse_protocol_thread = FALSE; @@ -4131,16 +4154,18 @@ static void test_binding(int prot, DWORD grf_pi, DWORD test_flags) CHECK_CALLED(ReportData); /* Set in ReportResult */ ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); }else { - if(mimefilter_test) - SET_EXPECT(MimeFilter_LockRequest); - else - SET_EXPECT(LockRequest); - hres = IInternetProtocol_LockRequest(protocol, 0); - ok(hres == S_OK, "LockRequest failed: %08x\n", hres); - if(mimefilter_test) - CHECK_CALLED(MimeFilter_LockRequest); - else - CHECK_CALLED(LockRequest); + if(!result_from_lock) { + if(mimefilter_test) + SET_EXPECT(MimeFilter_LockRequest); + else + SET_EXPECT(LockRequest); + hres = IInternetProtocol_LockRequest(protocol, 0); + ok(hres == S_OK, "LockRequest failed: %08x\n", hres); + if(mimefilter_test) + CHECK_CALLED(MimeFilter_LockRequest); + else + CHECK_CALLED(LockRequest); + } if(mimefilter_test) SET_EXPECT(MimeFilter_UnlockRequest); @@ -4284,7 +4309,7 @@ START_TEST(protocol) test_CreateBinding(); no_aggregation = FALSE; - bindf &= ~BINDF_FROMURLMON; + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_NOWRITECACHE | BINDF_PULLDATA; trace("Testing file binding (mime verification, emulate prot)...\n"); test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT); trace("Testing http binding (mime verification, emulate prot)...\n"); @@ -4307,6 +4332,8 @@ START_TEST(protocol) test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ); trace("Testing http binding (mime verification, emulate prot, abort)...\n"); test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT); + trace("Testing its binding (mime verification, emulate prot, apartment thread)...\n"); + test_binding(ITS_TEST, PI_MIMEVERIFICATION | PI_APARTMENTTHREADED, TEST_EMULATEPROT | TEST_RESULTFROMLOCK); if(pCreateUri) { trace("Testing file binding (use IUri, mime verification, emulate prot)...\n"); test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);