On Mon, Oct 07, 2019 at 02:19:18PM +0300, Paul Gofman wrote:
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com> --- The motivation under this patch is fixing the crash in Halo Online which originates from libcef.dll with Wine Staging. The crash scenario is the following.
A staging patch puts a 'Times New Roman' font replacement to <datadir>/fonts/times.ttf. This is the only relevant difference introduced by Staging. When the font file is found there, gdi32 uses wine_get_data_dir() for a directory prefix to construct font file name. Later libcef.dll works with fonts through dwrite, and somehow gets confused by a "\\..\\" inside the font file name which it gets with IDWriteLocalFontFileLoader_GetFilePathFromKey() from system font file enumerator object.
dlls/gdi32/freetype.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index e3cff25b76..2f21ba40a0 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -3168,11 +3168,33 @@ static void update_reg_entries(void) HeapFree( GetProcessHeap(), 0, buffer );
if (path) - file = path; + { + len = GetFullPathNameW(path, 0, NULL, NULL); + if (!(file = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*file)))) + { + HeapFree(GetProcessHeap(), 0, path); + HeapFree(GetProcessHeap(), 0, valueW); + continue; + } + if (GetFullPathNameW(path, len, file, NULL) != len - 1) + { + ERR("Could not get full path name, path %s.\n", debugstr_w(path)); + HeapFree(GetProcessHeap(), 0, file); + HeapFree(GetProcessHeap(), 0, path); + HeapFree(GetProcessHeap(), 0, valueW); + continue; + } + HeapFree(GetProcessHeap(), 0, path); + path = file; + }
All of these error paths are clumsy. Let's add a helper: WCHAR *get_full_path_name(const WCHAR *name) Note it should also check the return value of the first GetFullPathNameW call unlike the above. It would be used instead of the above if block something like: if (path) { if (fullpath = get_full_path_name(path)) { HeapFree(GetProcessHeap(), 0, path); path = fullpath; } file = path; }
else if ((file = strrchrW(face->file, '/'))) + { file++; + } else + { file = face->file; + }
Huw.