Module: wine Branch: master Commit: 4d02f2fed6e5dde284ec7e1b170ff9704a0bf3d1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4d02f2fed6e5dde284ec7e1b17...
Author: Piotr Caban piotr@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@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);