[PATCH v6 1/2] gdi32: In AddFaceToList allow fonts with long names and add tests

Fabian Maurer dark.shadow4 at web.de
Sun Nov 26 07:33:17 CST 2017


v4
remove global variable
don't check if functions are available
fix RemoveFontResourceExA test
properly release dc
add another test for completeness sake
v6
Don't truncate strings, instead only compare up to LF_FACESIZE - 1 characters
Also fix copying of the strings if they should be too long

Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/gdi32/freetype.c              |  45 +++++++++++--------------
 dlls/gdi32/tests/font.c            |  54 ++++++++++++++++++++++++++++++
 dlls/gdi32/tests/resource.rc       |   3 ++
 dlls/gdi32/tests/wine_longname.sfd |  66 +++++++++++++++++++++++++++++++++++++
 dlls/gdi32/tests/wine_longname.ttf | Bin 0 -> 2252 bytes
 5 files changed, 142 insertions(+), 26 deletions(-)
 create mode 100644 dlls/gdi32/tests/wine_longname.sfd
 create mode 100644 dlls/gdi32/tests/wine_longname.ttf

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 346e21dc21..7c5a7ef979 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1027,7 +1027,7 @@ static Face *find_face_from_filename(const WCHAR *file_name, const WCHAR *face_n
     LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
     {
         const struct list *face_list;
-        if(face_name && strcmpiW(face_name, family->FamilyName))
+        if(face_name && strncmpiW(face_name, family->FamilyName, LF_FACESIZE - 1))
             continue;
         face_list = get_face_list_from_family(family);
         LIST_FOR_EACH_ENTRY(face, face_list, Face, entry)
@@ -1053,7 +1053,7 @@ static Family *find_family_from_name(const WCHAR *name)
 
     LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
     {
-        if(!strcmpiW(family->FamilyName, name))
+        if(!strncmpiW(family->FamilyName, name, LF_FACESIZE -1))
             return family;
     }
 
@@ -1066,9 +1066,9 @@ static Family *find_family_from_any_name(const WCHAR *name)
 
     LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
     {
-        if(!strcmpiW(family->FamilyName, name))
+        if(!strncmpiW(family->FamilyName, name, LF_FACESIZE - 1))
             return family;
-        if(family->EnglishName && !strcmpiW(family->EnglishName, name))
+        if(family->EnglishName && !strncmpiW(family->EnglishName, name, LF_FACESIZE - 1))
             return family;
     }
 
@@ -2141,13 +2141,6 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr
 
     face = create_face( ft_face, face_index, file, font_data_ptr, font_data_size, flags );
     family = get_family( ft_face, flags & ADDFONT_VERTICAL_FONT );
-    if (strlenW(family->FamilyName) >= LF_FACESIZE)
-    {
-        WARN("Ignoring %s because name is too long\n", debugstr_w(family->FamilyName));
-        release_face( face );
-        release_family( family );
-        return;
-    }
 
     if (insert_face_in_family_list( face, family ))
     {
@@ -2471,7 +2464,7 @@ static SYSTEM_LINKS *find_font_link(const WCHAR *name)
 
     LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
     {
-        if(!strcmpiW(font_link->font_name, name))
+        if(!strncmpiW(font_link->font_name, name, LF_FACESIZE - 1))
             return font_link;
     }
 
@@ -4320,7 +4313,7 @@ static BOOL move_to_front(const WCHAR *name)
     Family *family, *cursor2;
     LIST_FOR_EACH_ENTRY_SAFE(family, cursor2, &font_list, Family, entry)
     {
-        if(!strcmpiW(family->FamilyName, name))
+        if(!strncmpiW(family->FamilyName, name, LF_FACESIZE - 1))
         {
             list_remove(&family->entry);
             list_add_head(&font_list, &family->entry);
@@ -5476,8 +5469,8 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
 	   or if that's unavailable the first charset that the font supports.
 	*/
         LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
-            if (!strcmpiW(family->FamilyName, FaceName) ||
-                (psub && !strcmpiW(family->FamilyName, psub->to.name)))
+            if (!strncmpiW(family->FamilyName, FaceName, LF_FACESIZE - 1) ||
+                (psub && !strncmpiW(family->FamilyName, psub->to.name, LF_FACESIZE - 1)))
             {
                 font_link = find_font_link(family->FamilyName);
                 face_list = get_face_list_from_family(family);
@@ -5499,7 +5492,7 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
         LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
             face_list = get_face_list_from_family(family);
             LIST_FOR_EACH_ENTRY( face, face_list, Face, entry ) {
-                if(face->FullName && !strcmpiW(face->FullName, FaceName) &&
+                if(face->FullName && !strncmpiW(face->FullName, FaceName, LF_FACESIZE - 1) &&
                    (face->scalable || can_use_bitmap))
                 {
                     if (csi.fs.fsCsb[0] & face->fs.fsCsb[0] || !csi.fs.fsCsb[0])
@@ -5518,8 +5511,8 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
          */
         LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
         {
-            if(!strcmpiW(font_link->font_name, FaceName) ||
-               (psub && !strcmpiW(font_link->font_name,psub->to.name)))
+            if(!strncmpiW(font_link->font_name, FaceName, LF_FACESIZE - 1) ||
+               (psub && !strncmpiW(font_link->font_name,psub->to.name, LF_FACESIZE - 1)))
             {
                 TRACE("found entry in system list\n");
                 LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
@@ -5569,7 +5562,7 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
     else
         strcpyW(lf.lfFaceName, defSans);
     LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
-        if(!strcmpiW(family->FamilyName, lf.lfFaceName)) {
+        if(!strncmpiW(family->FamilyName, lf.lfFaceName, LF_FACESIZE - 1)) {
             font_link = find_font_link(family->FamilyName);
             face_list = get_face_list_from_family(family);
             LIST_FOR_EACH_ENTRY( face, face_list, Face, entry ) {
@@ -6037,20 +6030,20 @@ static BOOL family_matches(Family *family, const WCHAR *face_name)
     Face *face;
     const struct list *face_list;
 
-    if (!strcmpiW(face_name, family->FamilyName)) return TRUE;
+    if (!strncmpiW(face_name, family->FamilyName, LF_FACESIZE - 1)) return TRUE;
 
     face_list = get_face_list_from_family(family);
     LIST_FOR_EACH_ENTRY(face, face_list, Face, entry)
-        if (face->FullName && !strcmpiW(face_name, face->FullName)) return TRUE;
+        if (face->FullName && !strncmpiW(face_name, face->FullName, LF_FACESIZE - 1)) return TRUE;
 
     return FALSE;
 }
 
 static BOOL face_matches(const WCHAR *family_name, Face *face, const WCHAR *face_name)
 {
-    if (!strcmpiW(face_name, family_name)) return TRUE;
+    if (!strncmpiW(face_name, family_name, LF_FACESIZE - 1)) return TRUE;
 
-    return (face->FullName && !strcmpiW(face_name, face->FullName));
+    return (face->FullName && !strncmpiW(face_name, face->FullName, LF_FACESIZE - 1));
 }
 
 static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_charset_list *list,
@@ -6082,11 +6075,11 @@ static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_cha
         /* Font Replacement */
         if (family != face->family)
         {
-            strcpyW(elf.elfLogFont.lfFaceName, family->FamilyName);
+            lstrcpynW(elf.elfLogFont.lfFaceName, family->FamilyName, LF_FACESIZE);
             if (face->FullName)
-                strcpyW(elf.elfFullName, face->FullName);
+                lstrcpynW(elf.elfFullName, face->FullName, LF_FULLFACESIZE);
             else
-                strcpyW(elf.elfFullName, family->FamilyName);
+                lstrcpynW(elf.elfFullName, family->FamilyName, LF_FULLFACESIZE);
         }
         if (subst)
             strcpyW(elf.elfLogFont.lfFaceName, subst);
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 299fadbab1..bd04a8b6b1 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -6679,6 +6679,59 @@ static void test_GetCharWidthI(void)
     ReleaseDC(0, hdc);
 }
 
+static INT CALLBACK long_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lparam)
+{
+    BOOL *found_font = (BOOL *)lparam;
+    *found_font = TRUE;
+    return 1;
+}
+
+static void test_long_names(void)
+{
+    char ttf_name[MAX_PATH];
+    LOGFONTA font = {0};
+    HFONT handle_font;
+    BOOL found_font;
+    int ret;
+    HDC dc;
+
+    if (!write_ttf_file("wine_longname.ttf", ttf_name))
+    {
+        skip("Failed to create ttf file for testing\n");
+        return;
+    }
+
+    dc = GetDC(NULL);
+
+    ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0);
+    ok(ret, "AddFontResourceEx() failed\n");
+
+    strcpy(font.lfFaceName, "wine_3_this_is_a_very_long_name");
+    found_font = FALSE;
+    EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
+    ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n");
+
+    strcpy(font.lfFaceName, "wine_2_this_is_a_very_long_name");
+    found_font = FALSE;
+    EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
+    ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n");
+
+    strcpy(font.lfFaceName, "wine_1_this_is_a_very_long_name");
+    found_font = FALSE;
+    EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
+    ok(found_font == FALSE, "EnumFontFamiliesExA must not find font.\n");
+
+    handle_font = CreateFontIndirectA(&font);
+    ok(handle_font != NULL, "CreateFontIndirectA failed\n");
+    DeleteObject(handle_font);
+
+    ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
+    ok(ret, "RemoveFontResourceEx() failed\n");
+
+    DeleteFileA(ttf_name);
+    ReleaseDC(NULL, dc);
+}
+
 START_TEST(font)
 {
     init();
@@ -6742,6 +6795,7 @@ START_TEST(font)
     test_fake_bold_font();
     test_bitmap_font_glyph_index();
     test_GetCharWidthI();
+    test_long_names();
 
     /* These tests should be last test until RemoveFontResource
      * is properly implemented.
diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc
index fdd95f687a..6dcbd42ab5 100644
--- a/dlls/gdi32/tests/resource.rc
+++ b/dlls/gdi32/tests/resource.rc
@@ -28,3 +28,6 @@ wine_vdmx.ttf RCDATA wine_vdmx.ttf
 
 /* @makedep: vertical.ttf */
 vertical.ttf RCDATA vertical.ttf
+
+/* @makedep: wine_longname.ttf */
+wine_longname.ttf RCDATA wine_longname.ttf
diff --git a/dlls/gdi32/tests/wine_longname.sfd b/dlls/gdi32/tests/wine_longname.sfd
new file mode 100644
index 0000000000..998d7cc01f
--- /dev/null
+++ b/dlls/gdi32/tests/wine_longname.sfd
@@ -0,0 +1,66 @@
+SplineFontDB: 3.0
+FontName: wine_1_this_is_a_very_long_name_that_might_be_too_long_for_gdi32
+FullName: wine_2_this_is_a_very_long_name_that_might_be_too_long_for_gdi32
+FamilyName: wine_3_this_is_a_very_long_name_that_might_be_too_long_for_gdi32
+Weight: Regular
+Copyright: Copyright (c) 2017, Fabian Maurer
+UComments: "2017-11-17: Created with FontForge (http://fontforge.org)"
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -102.4
+UnderlineWidth: 51.2
+Ascent: 819
+Descent: 205
+InvalidEm: 0
+LayerCount: 2
+Layer: 0 0 "Back" 1
+Layer: 1 0 "Fore" 0
+XUID: [1021 48 28337276 3092883]
+OS2Version: 0
+OS2_WeightWidthSlopeOnly: 0
+OS2_UseTypoMetrics: 1
+CreationTime: 1510948643
+ModificationTime: 1510949092
+OS2TypoAscent: 0
+OS2TypoAOffset: 1
+OS2TypoDescent: 0
+OS2TypoDOffset: 1
+OS2TypoLinegap: 0
+OS2WinAscent: 0
+OS2WinAOffset: 1
+OS2WinDescent: 0
+OS2WinDOffset: 1
+HheadAscent: 0
+HheadAOffset: 1
+HheadDescent: 0
+HheadDOffset: 1
+OS2Vendor: 'PfEd'
+MarkAttachClasses: 1
+DEI: 91125
+Encoding: ISO8859-1
+UnicodeInterp: none
+NameList: AGL For New Fonts
+DisplaySize: -48
+AntiAlias: 1
+FitToEm: 0
+WinInfo: 64 16 4
+BeginPrivate: 0
+EndPrivate
+BeginChars: 256 1
+
+StartChar: at
+Encoding: 64 64 0
+Width: 1024
+VWidth: 0
+Flags: HW
+LayerCount: 2
+Fore
+SplineSet
+259 332 m 29
+ 468 664 l 29
+ 514 332 l 29
+ 259 332 l 29
+EndSplineSet
+EndChar
+EndChars
+EndSplineFont
diff --git a/dlls/gdi32/tests/wine_longname.ttf b/dlls/gdi32/tests/wine_longname.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..59d9517560592e9578f1510f99f4fb65065c1195
GIT binary patch
literal 2252
zcmdT`J!~6Q9RIz$vy(ze6NyY%=$Z!6pv1io)Gv83{V*L80j0`9(dA;F&nMYF>wHP-
zEn;Fof`I`fHnvbz#A0FuAu(hCArJ#BOqEKh7`jo+ at 4dUk$yy{T-ueID|MR{7*WEJ&
zfGKQ4$6Bp+W96OM-;M#3pOag9^~%*6X7McP4<-HDn`fNWg1-fb7U{Km$M4}p at gC`)
z376`dsfju5T|h5UZiIfnHyUwgOuk2YGHef;-|P-8$`?uZT7lnq=Jxy@;=dElw#X<P
zGYZ^mp7eaHlioTG at dD{@Nl&-qx{r0-puI`@sg8fEhikY%`8CpJ*Y5=DvzvRAf5PLx
z>c#zZw1cxedX4gzAY&y=efL?(J5hOvrwuZIpI(0OX}12^z#O1y+79VSXp+l88^yVq
z>1&$WDU)Thp*Y5YjkFYsS4CN=7*zQHj7|Gkqlb7uTg5%Nf*IFP;G7TX=fQZrd9}g%
zR8iI4k&Bzk6Xnx^iU~o_=sBZSAeeKRcLk-~+X^YUbBRhOSA&nFtE`clM_=cf5XJEU
zLdGKD at Hpb(VZj)e$N$fV>Sgwge9ki#P3BlQtbmRQly?QrRE84<?mN51!Y`Gft`Wtq
zF4+ai9!?a+UzH(Kc;9hnPR_jO&YYSP(|_#kX*-Wr=d>ob6S`Pt$9*JoES at 9zeOWAv
z<-fm>$(zER{hHt;uH?8t6?b!7!-Tky<2v3Jk8<2VRr at u^3z*icIbLKR{UAHRko|Uv
zkl}(o*35AYQ(_^<b$lsa$#DbQ+FLnZfT=&9<3()iZ{RXw^e{kz2q9WX*=46u#{yRe
z7HpiuBJmpJTO4ujl3L-qL7RYp%W-dzL}4p6PuCYr$Fk2Ynl*nt^1J4WzmWt~*`j5a
z+8$g&%5x(0iDk1-Y*XzuAl9ZwUHam2_R&#R(!!^mM|$5+kN(IVQ|iY@?3$z#azZqy
z?J^E*Mcu%2y|fkeJ^p-eGe`zrJMM;_`~Xqlr(Q<};jNR3<4o3!6EAE;E_b-j!$Jn#
zrX!5#dJt~3eIhmGZmQOV8i7h&nW-~zkuVP3QO^F?p=Vy$d=-{hOq=t5Sy79-X)R8|
zz;w!%dC^o!avncP+`>M;WZO%!2M!ng$wZzN{a?fbtg at U5J2g^8Hd$2pM#$pI$D~4#
z^rN_IT9#e5EQ_3Rz3nGb?<{Kj at vF#>%l^$V+UDEC51eEj8S=ss)H<cOf_KsQc0JDj
V9#YOPqq5Ab)%@daq1MB9_dm8?dc^<$

literal 0
HcmV?d00001

-- 
2.15.0




More information about the wine-devel mailing list