riched20: Avoid releasing a non-existent interface.

Jactry Zeng jactry92 at gmail.com
Wed Apr 16 08:37:55 CDT 2014


Hi Nikolay,

Thanks for your review!

The crash can be reproduced follow this:
- first release the ITextSelection or IOleClientSite interfaces completely;
- release ITextDocument interface;
- try to release the IRichEditOle (crash happen)

And this patch try to fix it.


(tests in attachment can reproduce the crash.)


2014-04-16 18:59 GMT+08:00 Nikolay Sivov <bunglehead at gmail.com>:

>  -        This->txtSel->reOle = NULL;
>> -        ITextSelection_Release(&This->txtSel->ITextSelection_iface);
>> -        IOleClientSite_Release(&This->clientSite->IOleClientSite_iface);
>> +        if(This->txtSel)
>> +          {
>> +            This->txtSel->reOle = NULL;
>> +            ITextSelection_Release(&This->txtSel->ITextSelection_iface);
>> +          }
>> +        if(This->clientSite)
>> +          {
>> +            This->clientSite->reOle = NULL;
>> +            IOleClientSite_Release(&This->clientSite->IOleClientSite_
>> iface);
>> +          }
>>           heap_fr
>>
> This can't happen.
>
>        IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
>>       ULONG ref = InterlockedDecrement(&This->ref);
>>       if (ref == 0)
>> +      {
>> +        if(This->reOle)
>> +          This->reOle->clientSite = NULL;
>>           heap_free(This);
>> +      }
>>       return ref;
>>
> Why do you need this?
>



-- 
Regards,
Jactry Zeng
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20140416/4a6306df/attachment.html>
-------------- next part --------------
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index 5a3ffbe..7c55692 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -385,6 +385,34 @@ static void test_ITextDocument_Open(void)
   VariantClear(&testfile);
 }
 
+void test_COM(void)
+{
+  HRESULT hres;
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  IOleClientSite *clientSite = NULL;
+  /* ITextSelection *txtSel = NULL; */
+
+  w = new_richedit(NULL);
+  SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
+  hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
+                                     (void **) &txtDoc);
+  ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
+  hres = IRichEditOle_GetClientSite(reOle, &clientSite);
+  ok(hres == S_OK, "IRichEditOle_GetClientSite\n");
+
+  /* hres = ITextDocument_GetSelection(txtDoc, &txtSel); */
+  /* ok(hres == S_OK, "ITextDocument_GetSelection\n"); */
+  /* while(ITextSelection_Release(txtSel)); */
+  /* ITextDocument_Release(txtDoc); */
+  /* IRichEditOle_Release(reOle); */
+
+  while(IOleClientSite_Release(clientSite));
+  ITextDocument_Release(txtDoc);
+  IRichEditOle_Release(reOle);
+}
+
 START_TEST(richole)
 {
   /* Must explicitly LoadLibrary(). The test has no references to functions in
@@ -394,4 +422,5 @@ START_TEST(richole)
 
   test_Interfaces();
   test_ITextDocument_Open();
+  test_COM();
 }


More information about the wine-devel mailing list