Jacek Caban : urlmon: Don't allow direct sink callbacks when reporting data.
Alexandre Julliard
julliard at winehq.org
Fri Jan 7 15:04:52 CST 2022
Module: wine
Branch: master
Commit: 7c037c82c8c56539dd03e00628e27e4525b66483
URL: https://source.winehq.org/git/wine.git/?a=commit;h=7c037c82c8c56539dd03e00628e27e4525b66483
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Jan 6 19:30:37 2022 +0100
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 <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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);
More information about the wine-cvs
mailing list