Huw Davies : gdi32/tests: Allocate the font enum data structures.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Apr 14 11:48:51 CDT 2016


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Apr 14 11:12:35 2016 +0100

gdi32/tests: Allocate the font enum data structures.

These are in excess of 250kB and may overflow the stack.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/tests/font.c | 119 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 82 insertions(+), 37 deletions(-)

diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index a1917b4..eb6669b 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -107,6 +107,22 @@ static void init(void)
     system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID());
 }
 
+static void *heap_alloc( size_t len )
+{
+    return HeapAlloc( GetProcessHeap(), 0, len );
+}
+
+static void *heap_realloc( void *p, size_t len )
+{
+    if (!p) return heap_alloc( len );
+    return HeapReAlloc( GetProcessHeap(), 0, p, len );
+}
+
+static void heap_free( void *p )
+{
+    HeapFree( GetProcessHeap(), 0, p );
+}
+
 static INT CALLBACK is_truetype_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
     if (type != TRUETYPE_FONTTYPE) return 1;
@@ -2736,24 +2752,22 @@ static void test_GetFontUnicodeRanges(void)
     ReleaseDC(NULL, hdc);
 }
 
-#define MAX_ENUM_FONTS 4096
-
 struct enum_font_data
 {
-    int total;
-    LOGFONTA lf[MAX_ENUM_FONTS];
+    int total, size;
+    LOGFONTA *lf;
 };
 
 struct enum_fullname_data
 {
-    int total;
-    ENUMLOGFONTA elf[MAX_ENUM_FONTS];
+    int total, size;
+    ENUMLOGFONTA *elf;
 };
 
 struct enum_font_dataW
 {
-    int total;
-    LOGFONTW lf[MAX_ENUM_FONTS];
+    int total, size;
+    LOGFONTW *lf;
 };
 
 static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
@@ -2771,10 +2785,13 @@ static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, D
     if (0) /* Disabled to limit console spam */
         trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n",
               lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
-    if (efd->total < MAX_ENUM_FONTS)
-        efd->lf[efd->total++] = *lf;
-    else
-        trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
+    if (efd->total >= efd->size)
+    {
+        efd->size = max( (efd->total + 1) * 2, 256 );
+        efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
+        if (!efd->lf) return 0;
+    }
+    efd->lf[efd->total++] = *lf;
 
     return 1;
 }
@@ -2794,10 +2811,13 @@ static INT CALLBACK arial_enum_procw(const LOGFONTW *lf, const TEXTMETRICW *tm,
     if (0) /* Disabled to limit console spam */
         trace("enumed font %s, charset %d, height %d, weight %d, italic %d\n",
               wine_dbgstr_w(lf->lfFaceName), lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
-    if (efd->total < MAX_ENUM_FONTS)
-        efd->lf[efd->total++] = *lf;
-    else
-        trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
+    if (efd->total >= efd->size)
+    {
+        efd->size = max( (efd->total + 1) * 2, 256 );
+        efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
+        if (!efd->lf) return 0;
+    }
+    efd->lf[efd->total++] = *lf;
 
     return 1;
 }
@@ -2871,6 +2891,8 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset)
         skip("%s is not installed\n", font_name);
         return;
     }
+    memset( &efd, 0, sizeof(efd) );
+    memset( &efdw, 0, sizeof(efdw) );
 
     hdc = GetDC(0);
 
@@ -3064,6 +3086,9 @@ else
     }
 
     ReleaseDC(0, hdc);
+
+    heap_free( efd.lf );
+    heap_free( efdw.lf );
 }
 
 static INT CALLBACK enum_multi_charset_font_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
@@ -3093,10 +3118,13 @@ static INT CALLBACK enum_font_data_proc(const LOGFONTA *lf, const TEXTMETRICA *n
 
     if (type != TRUETYPE_FONTTYPE) return 1;
 
-    if (efd->total < MAX_ENUM_FONTS)
-        efd->lf[efd->total++] = *lf;
-    else
-        trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
+    if (efd->total >= efd->size)
+    {
+        efd->size = max( (efd->total + 1) * 2, 256 );
+        efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
+        if (!efd->lf) return 0;
+    }
+    efd->lf[efd->total++] = *lf;
 
     return 1;
 }
@@ -3107,10 +3135,13 @@ static INT CALLBACK enum_fullname_data_proc(const LOGFONTA *lf, const TEXTMETRIC
 
     if (type != TRUETYPE_FONTTYPE) return 1;
 
-    if (efnd->total < MAX_ENUM_FONTS)
-        efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
-    else
-        trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
+    if (efnd->total >= efnd->size)
+    {
+        efnd->size = max( (efnd->total + 1) * 2, 256 );
+        efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
+        if (!efnd->elf) return 0;
+    }
+    efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
 
     return 1;
 }
@@ -3144,7 +3175,7 @@ static void test_EnumFontFamiliesEx_default_charset(void)
         target.lfCharSet = ANSI_CHARSET;
     }
 
-    efd.total = 0;
+    memset(&efd, 0, sizeof(efd));
     memset(&enum_font, 0, sizeof(enum_font));
     strcpy(enum_font.lfFaceName, target.lfFaceName);
     enum_font.lfCharSet = DEFAULT_CHARSET;
@@ -3152,15 +3183,14 @@ static void test_EnumFontFamiliesEx_default_charset(void)
     ReleaseDC(0, hdc);
 
     trace("'%s' has %d charsets.\n", target.lfFaceName, efd.total);
-    if (efd.total < 2) {
+    if (efd.total < 2)
         ok(0, "EnumFontFamilies is broken. Expected >= 2, got %d.\n", efd.total);
-        return;
-    }
-
-    ok(efd.lf[0].lfCharSet == target.lfCharSet,
-       "(%s) got charset %d expected %d\n",
-       efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
+    else
+        ok(efd.lf[0].lfCharSet == target.lfCharSet,
+           "(%s) got charset %d expected %d\n",
+           efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
 
+    heap_free(efd.lf);
     return;
 }
 
@@ -5215,6 +5245,12 @@ if (0) /* Disabled to limit console spam */
     if (type != TRUETYPE_FONTTYPE) return 1;
     if (strcmp(lf->lfFaceName, "MS Shell Dlg") != 0) return 1;
 
+    if (efnd->total >= efnd->size)
+    {
+        efnd->size = max( (efnd->total + 1) * 2, 256 );
+        efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
+        if (!efnd->elf) return 0;
+    }
     efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
     return 0;
 }
@@ -5230,6 +5266,12 @@ if (0) /* Disabled to limit console spam */
     if (type != TRUETYPE_FONTTYPE) return 1;
     if (strcmp(lf->lfFaceName, "MS Shell Dlg 2") != 0) return 1;
 
+    if (efnd->total >= efnd->size)
+    {
+        efnd->size = max( (efnd->total + 1) * 2, 256 );
+        efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
+        if (!efnd->elf) return 0;
+    }
     efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
     return 0;
 }
@@ -5261,7 +5303,7 @@ static void test_EnumFonts_subst(void)
     memset(&lf, 0, sizeof(lf));
     lf.lfCharSet = DEFAULT_CHARSET;
 
-    memset(&efnd, 0, sizeof(efnd));
+    efnd.total = 0;
     strcpy(lf.lfFaceName, "MS Shell Dlg");
     ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg_proc, (LPARAM)&efnd, 0);
     ok(!ret, "MS Shell Dlg should be enumerated\n");
@@ -5271,12 +5313,12 @@ static void test_EnumFonts_subst(void)
     ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg");
     ok(ret, "did not expect MS Shell Dlg\n");
 
-    memset(&efnd, 0, sizeof(efnd));
+    efnd.total = 0;
     ret = EnumFontFamiliesExA(hdc, NULL, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0);
     ok(ret, "MS Shell Dlg 2 should not be enumerated\n");
     ok(!efnd.total, "MS Shell Dlg 2 should not be enumerated\n");
 
-    memset(&efnd, 0, sizeof(efnd));
+    efnd.total = 0;
     strcpy(lf.lfFaceName, "MS Shell Dlg 2");
     ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0);
     ok(!ret, "MS Shell Dlg 2 should be enumerated\n");
@@ -5286,6 +5328,7 @@ static void test_EnumFonts_subst(void)
     ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg 2");
     ok(ret, "did not expect MS Shell Dlg 2\n");
 
+    heap_free(efnd.elf);
     DeleteDC(hdc);
 }
 
@@ -5396,7 +5439,7 @@ static void test_fullname2_helper(const char *Family)
     lf.lfItalic = FALSE;
     lf.lfWeight = FW_DONTCARE;
     strcpy(lf.lfFaceName, Family);
-    efnd.total = 0;
+    memset(&efnd, 0, sizeof(efnd));
     EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
     if (efnd.total == 0)
         skip("%s is not installed\n", lf.lfFaceName);
@@ -5477,6 +5520,7 @@ static void test_fullname2_helper(const char *Family)
         HeapFree(GetProcessHeap(), 0, bufW);
         HeapFree(GetProcessHeap(), 0, bufA);
     }
+    heap_free(efnd.elf);
     DeleteDC(hdc);
 }
 
@@ -6225,7 +6269,7 @@ static void test_vertical_order(void)
     lf.lfQuality = DEFAULT_QUALITY;
     lf.lfItalic = FALSE;
     lf.lfWeight = FW_DONTCARE;
-    efd.total = 0;
+    memset( &efd, 0, sizeof(efd) );
     EnumFontFamiliesExA(hdc, &lf, enum_font_data_proc, (LPARAM)&efd, 0);
     for (i = 0; i < efd.total; i++)
     {
@@ -6239,6 +6283,7 @@ static void test_vertical_order(void)
             }
         }
     }
+    heap_free( efd.lf );
     DeleteDC( hdc );
 }
 




More information about the wine-cvs mailing list