File fontforge-fix-multiple-crashes-in-Multiple-Masters.patch of Package fontforge

From dfe5c8035d716e99ebd0fdb1c49ea623d94737a7 Mon Sep 17 00:00:00 2001
From: Maxim Iorsh <iorsh@users.sourceforge.net>
Date: Mon, 19 Jan 2026 22:45:20 +0200
Subject: [PATCH] Fix multiple crashes in Multiple Masters (#5733)

* Fix corruption in SFMakeChar() for MM fonts
* Crash when opening MM font with kerning
* Fix crash for missing MM Mac name
---
 Unicode/memory.c     |  7 +++++++
 Unicode/ustring.c    |  2 +-
 fontforge/encoding.c | 40 ++++++++++++++++++++++++++--------------
 fontforge/sfd.c      |  4 +++-
 fontforgeexe/mmdlg.c |  6 +++---
 inc/basics.h         |  2 ++
 6 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/Unicode/memory.c b/Unicode/memory.c
index 774b138fd..1613f7730 100644
--- a/Unicode/memory.c
+++ b/Unicode/memory.c
@@ -39,6 +39,13 @@ void NoMoreMemMessage(void) {
     fprintf(stderr, "Out of memory\n" );
 }
 
+void ExpandBuffer(void** p_buf, size_t elem_size, size_t increment,
+                  int* p_maxalloc) {
+    *p_buf = realloc(*p_buf, (*p_maxalloc + increment) * elem_size);
+    memset((char*)*p_buf + (*p_maxalloc) * elem_size, 0, increment * elem_size);
+    *p_maxalloc += increment;
+}
+
 char *copy(const char *str) {
     return str ? strdup(str) : NULL;
 }
diff --git a/Unicode/ustring.c b/Unicode/ustring.c
index b0fe3387e..893eeedf2 100644
--- a/Unicode/ustring.c
+++ b/Unicode/ustring.c
@@ -535,7 +535,7 @@ unichar_t *utf82u_strncpy(unichar_t *ubuf,const char *utf8buf,int len) {
 }
 
 unichar_t *utf82u_strcpy(unichar_t *ubuf,const char *utf8buf) {
-return( utf82u_strncpy(ubuf,utf8buf,strlen(utf8buf)+1));
+return( utf82u_strncpy(ubuf,utf8buf,c_strlen(utf8buf)+1));
 }
 
 unichar_t *utf82u_copyn(const char *utf8buf,int len) {
diff --git a/fontforge/encoding.c b/fontforge/encoding.c
index 194ecd035..6eb9c6dc7 100644
--- a/fontforge/encoding.c
+++ b/fontforge/encoding.c
@@ -1233,7 +1233,7 @@ enum cmaptype { cmt_out=-1, cmt_coderange, cmt_notdefs, cmt_cid, cmt_max };
 struct coderange { uint32_t first, last, cid; };
 struct cmap {
     struct {
-	int n;
+	size_t n;
 	struct coderange *ranges;
     } groups[cmt_max];
     char *registry;
@@ -1253,7 +1253,7 @@ static void cmapfree(struct cmap *cmap) {
     free(cmap);
 }
 
-static struct coderange *ExtendArray(struct coderange *ranges,int *n, int val) {
+static struct coderange *ExtendArray(struct coderange *ranges, size_t *n, int val) {
     if ( *n == 0 )
 	ranges = calloc(val,sizeof(struct coderange));
     else {
@@ -1280,7 +1280,8 @@ static struct cmap *ParseCMap(char *filename) {
     FILE *file;
     struct cmap *cmap;
     char *end, *pt;
-    int val, pos;
+    int val;
+    size_t pos;
     enum cmaptype in;
     int in_is_single; // We set this if we are to parse cidchars into cidranges.
     static const char *bcsr = "begincodespacerange", *bndr = "beginnotdefrange", *bcr = "begincidrange", *bcc = "begincidchar";
@@ -2363,21 +2364,32 @@ return( any );
 }
 
 void SFAddGlyphAndEncode(SplineFont *sf,SplineChar *sc,EncMap *basemap, int baseenc) {
-    int gid, mapfound = false;
+    int j, gid, mapfound = false;
     FontViewBase *fv;
     BDFFont *bdf;
 
     if ( sf->cidmaster==NULL ) {
-	if ( sf->glyphcnt+1>=sf->glyphmax )
-	    sf->glyphs = realloc(sf->glyphs,(sf->glyphmax+=10)*sizeof(SplineChar *));
-	gid = sf->glyphcnt++;
-	for ( bdf = sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
-	    if ( sf->glyphcnt+1>=bdf->glyphmax )
-		bdf->glyphs = realloc(bdf->glyphs,(bdf->glyphmax=sf->glyphmax)*sizeof(BDFChar *));
-	    if ( sf->glyphcnt>bdf->glyphcnt ) {
-		memset(bdf->glyphs+bdf->glyphcnt,0,(sf->glyphcnt-bdf->glyphcnt)*sizeof(BDFChar *));
-		bdf->glyphcnt = sf->glyphcnt;
-	    }
+        if (sf->glyphcnt + 1 > sf->glyphmax)
+            ExpandBuffer((void**)&sf->glyphs, sizeof(SplineChar*), 10,
+                         &sf->glyphmax);
+        gid = sf->glyphcnt++;
+        for (bdf = sf->bitmaps; bdf != NULL; bdf = bdf->next) {
+            if (sf->glyphcnt + 1 > bdf->glyphmax)
+                ExpandBuffer((void**)&bdf->glyphs, sizeof(BDFChar*),
+                             sf->glyphmax - bdf->glyphmax, &bdf->glyphmax);
+        }
+        if (sf->mm != NULL) {
+            if (sf->mm->normal->glyphmax < sf->glyphmax)
+                ExpandBuffer((void**)&sf->mm->normal->glyphs,
+                             sizeof(SplineChar*),
+                             sf->glyphmax - sf->mm->normal->glyphmax,
+                             &sf->mm->normal->glyphmax);
+            for (j = 0; j < sf->mm->instance_count; ++j)
+                if (sf->mm->instances[j]->glyphmax < sf->glyphmax)
+                    ExpandBuffer((void**)&sf->mm->instances[j]->glyphs,
+                                 sizeof(SplineChar*),
+                                 sf->glyphmax - sf->mm->instances[j]->glyphmax,
+                                 &sf->mm->instances[j]->glyphmax);
 	}
 	for ( fv=sf->fv; fv!=NULL; fv = fv->nextsame ) {
 	    EncMap *map = fv->map;
diff --git a/fontforge/sfd.c b/fontforge/sfd.c
index a349d0b2f..f3c84080d 100644
--- a/fontforge/sfd.c
+++ b/fontforge/sfd.c
@@ -9014,7 +9014,9 @@ exit( 1 );
 	    }
 	}
     }
-    if ( sf->cidmaster==NULL )
+
+    /* MM font has already been already fixed up. */
+    if (sf->cidmaster == NULL && sf->mm == NULL)
 	SFDFixupRefs(sf);
 
     if ( !haddupenc )
diff --git a/fontforgeexe/mmdlg.c b/fontforgeexe/mmdlg.c
index 1baf9ffda..540afdd1c 100644
--- a/fontforgeexe/mmdlg.c
+++ b/fontforgeexe/mmdlg.c
@@ -1632,7 +1632,7 @@ return( NULL );
 	pt[-1] = ']';
 	ustyle = PickNameFromMacName(mmw->old->named_instances[i].names);
 	ti[i].bg = ti[i].fg = COLOR_DEFAULT;
-	ti[i].text = malloc((strlen(buffer)+3+strlen(ustyle))*sizeof(unichar_t));
+	ti[i].text = calloc(strlen(buffer)+3+c_strlen(ustyle), sizeof(unichar_t));
 	utf82u_strcpy(ti[i].text,ustyle);
 	uc_strcat(ti[i].text," ");
 	uc_strcat(ti[i].text,buffer);
@@ -1762,9 +1762,9 @@ static void MMW_ParseNamedStyles(MMSet *setto,MMW *mmw) {
 
 static void MMW_DoOK(MMW *mmw) {
     real weights[AppleMmMax+1];
-    real fbt;
+    real fbt = 0.;
     int err = false;
-    char *familyname, *fn, *origname=NULL;
+    char *familyname, *fn=NULL, *origname=NULL;
     int i,j;
     MMSet *setto, *dlgmm;
     FontView *fv = NULL;
diff --git a/inc/basics.h b/inc/basics.h
index 86f0db712..9204285d5 100644
--- a/inc/basics.h
+++ b/inc/basics.h
@@ -73,6 +73,8 @@ typedef uint32_t unichar_t;
 #endif
 
 extern void NoMoreMemMessage(void);
+extern void ExpandBuffer(void** p_buf, size_t elem_size, size_t increment,
+                         int* p_maxalloc);
 
 static inline int imin(int a, int b)
 {
-- 
2.49.0

openSUSE Build Service is sponsored by