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