Commit 81557b5e authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

gdi32: Do not crash on an invalid pointer passed to AddFontMemResourceEx.

parent a690db9f
......@@ -33,6 +33,7 @@
#include "winnls.h"
#include "wownt32.h"
#include "gdi_private.h"
#include "wine/exception.h"
#include "wine/unicode.h"
#include "wine/debug.h"
......@@ -3184,7 +3185,25 @@ BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
*/
HANDLE WINAPI AddFontMemResourceEx( PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts)
{
return WineEngAddFontMemResourceEx(pbFont, cbFont, pdv, pcFonts);
HANDLE ret;
DWORD num_fonts;
ret = WineEngAddFontMemResourceEx(pbFont, cbFont, pdv, &num_fonts);
if (ret)
{
__TRY
{
*pcFonts = num_fonts;
}
__EXCEPT_PAGE_FAULT
{
WARN("page fault while writing to *pcFonts (%p)\n", pcFonts);
RemoveFontMemResourceEx(ret);
ret = 0;
}
__ENDTRY
}
return ret;
}
/***********************************************************************
......
......@@ -2151,7 +2151,7 @@ HANDLE WineEngAddFontMemResourceEx(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD
{
TRACE("AddFontToList failed\n");
HeapFree(GetProcessHeap(), 0, pFontCopy);
return NULL;
return 0;
}
/* FIXME: is the handle only for use in RemoveFontMemResourceEx or should it be a true handle?
* For now return something unique but quite random
......
......@@ -44,6 +44,8 @@ DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi,
DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *);
HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *);
HANDLE (WINAPI *pAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
BOOL (WINAPI *pRemoveFontMemResourceEx)(HANDLE);
static HMODULE hgdi32 = 0;
......@@ -59,6 +61,8 @@ static void init(void)
pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW");
pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo");
pCreateFontIndirectExA = (void *)GetProcAddress(hgdi32, "CreateFontIndirectExA");
pAddFontMemResourceEx = (void *)GetProcAddress(hgdi32, "AddFontMemResourceEx");
pRemoveFontMemResourceEx = (void *)GetProcAddress(hgdi32, "RemoveFontMemResourceEx");
}
static INT CALLBACK is_truetype_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
......@@ -3142,6 +3146,84 @@ static void test_CreateFontIndirectEx(void)
DeleteObject(hfont);
}
static void free_font(void *font)
{
UnmapViewOfFile(font);
}
static void *load_font(const char *font_name, DWORD *font_size)
{
char file_name[MAX_PATH];
HANDLE file, mapping;
void *font;
if (!GetWindowsDirectory(file_name, sizeof(file_name))) return NULL;
strcat(file_name, "\\fonts\\");
strcat(file_name, font_name);
file = CreateFile(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
if (file == INVALID_HANDLE_VALUE) return NULL;
*font_size = GetFileSize(file, NULL);
mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (!mapping)
{
CloseHandle(file);
return NULL;
}
font = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
CloseHandle(file);
CloseHandle(mapping);
return font;
}
static void test_AddFontMemResource(void)
{
void *font;
DWORD font_size, num_fonts;
HANDLE ret;
if (!pAddFontMemResourceEx || !pRemoveFontMemResourceEx)
{
win_skip("AddFontMemResourceEx is not available on this platform\n");
return;
}
font = load_font("sserife.fon", &font_size);
if (!font)
{
skip("Unable to locate and load font sserife.fon\n");
return;
}
num_fonts = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pAddFontMemResourceEx(font, font_size, NULL, &num_fonts);
ok(ret != 0, "AddFontMemResourceEx error %d\n", GetLastError());
ok(num_fonts != 0xdeadbeef, "number of loaded fonts should not be 0xdeadbeef\n");
ok(num_fonts != 0, "number of loaded fonts should not be 0\n");
free_font(font);
SetLastError(0xdeadbeef);
ok(pRemoveFontMemResourceEx(ret), "RemoveFontMemResourceEx error %d\n", GetLastError());
/* test invalid pointer to number of loaded fonts */
font = load_font("sserife.fon", &font_size);
ok(font != NULL, "Unable to locate and load font sserife.fon\n");
ret = pAddFontMemResourceEx(font, font_size, NULL, (void *)0xdeadbeef);
ok(!ret, "AddFontMemResourceEx should fail\n");
ret = pAddFontMemResourceEx(font, font_size, NULL, NULL);
ok(!ret, "AddFontMemResourceEx should fail\n");
free_font(font);
}
START_TEST(font)
{
init();
......@@ -3162,6 +3244,7 @@ START_TEST(font)
test_nonexistent_font();
test_orientation();
test_height_selection();
test_AddFontMemResource();
/* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
* I'd like to avoid them in this test.
......
......@@ -3630,6 +3630,7 @@ WINGDIAPI UINT WINAPI RealizePalette(HDC);
WINGDIAPI BOOL WINAPI Rectangle(HDC,INT,INT,INT,INT);
WINGDIAPI BOOL WINAPI RectInRegion(HRGN,const RECT *);
WINGDIAPI BOOL WINAPI RectVisible(HDC,const RECT*);
WINGDIAPI BOOL WINAPI RemoveFontMemResourceEx(HANDLE);
WINGDIAPI BOOL WINAPI RemoveFontResourceA(LPCSTR);
WINGDIAPI BOOL WINAPI RemoveFontResourceW(LPCWSTR);
#define RemoveFontResource WINELIB_NAME_AW(RemoveFontResource)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment