Piotr Caban : dwrite: Fix EUDC font collection use after free issue.

Alexandre Julliard julliard at winehq.org
Thu Apr 27 15:49:10 CDT 2017


Module: wine
Branch: master
Commit: 4d02f2fed6e5dde284ec7e1b170ff9704a0bf3d1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4d02f2fed6e5dde284ec7e1b170ff9704a0bf3d1

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Apr 27 17:20:03 2017 +0200

dwrite: Fix EUDC font collection use after free issue.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dwrite/dwrite_private.h |  2 +-
 dlls/dwrite/font.c           |  6 ++++--
 dlls/dwrite/main.c           | 15 ++++++++-------
 dlls/dwrite/tests/font.c     |  3 +++
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 7dca5fb..0676b95 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -168,7 +168,7 @@ extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const W
 extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN;
 extern void    set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN;
 extern HRESULT get_system_fontcollection(IDWriteFactory4*,IDWriteFontCollection1**) DECLSPEC_HIDDEN;
-extern HRESULT get_eudc_fontcollection(IDWriteFactory4*,IDWriteFontCollection**) DECLSPEC_HIDDEN;
+extern HRESULT get_eudc_fontcollection(IDWriteFactory4*,IDWriteFontCollection1**) DECLSPEC_HIDDEN;
 extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN;
 extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
 extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 328e5e4..d5bed85 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -4052,7 +4052,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory4 *factory, struct dwrit
     return hr;
 }
 
-HRESULT get_eudc_fontcollection(IDWriteFactory4 *factory, IDWriteFontCollection **ret)
+HRESULT get_eudc_fontcollection(IDWriteFactory4 *factory, IDWriteFontCollection1 **ret)
 {
     static const WCHAR eudckeyfmtW[] = {'E','U','D','C','\\','%','u',0};
     struct dwrite_fontcollection *collection;
@@ -4078,7 +4078,9 @@ HRESULT get_eudc_fontcollection(IDWriteFactory4 *factory, IDWriteFontCollection
         return hr;
     }
 
-    *ret = (IDWriteFontCollection*)&collection->IDWriteFontCollection1_iface;
+    *ret = &collection->IDWriteFontCollection1_iface;
+    collection->factory = factory;
+    IDWriteFactory4_AddRef(factory);
 
     /* return empty collection if EUDC fonts are not configured */
     sprintfW(eudckeypathW, eudckeyfmtW, GetACP());
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 73fcb51..a99bd95 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -537,7 +537,7 @@ struct dwritefactory {
     LONG ref;
 
     IDWriteFontCollection1 *system_collection;
-    IDWriteFontCollection *eudc_collection;
+    IDWriteFontCollection1 *eudc_collection;
     IDWriteGdiInterop1 *gdiinterop;
     IDWriteFontFallback *fallback;
 
@@ -592,7 +592,7 @@ static void release_dwritefactory(struct dwritefactory *factory)
     if (factory->system_collection)
         IDWriteFontCollection1_Release(factory->system_collection);
     if (factory->eudc_collection)
-        IDWriteFontCollection_Release(factory->eudc_collection);
+        IDWriteFontCollection1_Release(factory->eudc_collection);
     if (factory->fallback)
         release_system_fontfallback(factory->fallback);
     heap_free(factory);
@@ -1201,13 +1201,12 @@ static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory4 *ifac
     if (check_for_updates)
         FIXME("checking for eudc updates not implemented\n");
 
-    if (!This->eudc_collection)
+    if (This->eudc_collection)
+        IDWriteFontCollection1_AddRef(This->eudc_collection);
+    else
         hr = get_eudc_fontcollection(iface, &This->eudc_collection);
 
-    if (SUCCEEDED(hr))
-        IDWriteFontCollection_AddRef(This->eudc_collection);
-
-    *collection = This->eudc_collection;
+    *collection = (IDWriteFontCollection*)This->eudc_collection;
 
     return hr;
 }
@@ -1665,6 +1664,8 @@ void factory_detach_fontcollection(IDWriteFactory4 *iface, IDWriteFontCollection
     struct dwritefactory *factory = impl_from_IDWriteFactory4(iface);
     if (factory->system_collection == collection)
         factory->system_collection = NULL;
+    if (factory->eudc_collection == collection)
+        factory->eudc_collection = NULL;
     IDWriteFactory4_Release(iface);
 }
 
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 980278e..2d1b550 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -4366,10 +4366,13 @@ static void test_GetEudcFontCollection(void)
         return;
     }
 
+    EXPECT_REF(factory1, 1);
     hr = IDWriteFactory1_GetEudcFontCollection(factory1, &coll, FALSE);
     ok(hr == S_OK, "got 0x%08x\n", hr);
+    EXPECT_REF(factory1, 2);
     hr = IDWriteFactory1_GetEudcFontCollection(factory1, &coll2, FALSE);
     ok(hr == S_OK, "got 0x%08x\n", hr);
+    EXPECT_REF(factory1, 2);
     ok(coll == coll2, "got %p, %p\n", coll, coll2);
     IDWriteFontCollection_Release(coll);
     IDWriteFontCollection_Release(coll2);




More information about the wine-cvs mailing list