fontconfig: Branch 'main' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 12 12:15:10 UTC 2025


 .gitlab-ci/build.sh       |    2 -
 fc-fontations/meson.build |   10 ++---
 meson.build               |    2 -
 src/Makefile.am           |    1 
 src/fccache.c             |   78 +++++++++++++++++++++++++++++++++++++++++++---
 src/fcint.h               |   18 ++++++++++
 src/fclang.c              |   18 ----------
 src/meson.build           |    4 +-
 test/meson.build          |    2 -
 9 files changed, 103 insertions(+), 32 deletions(-)

New commits:
commit 2bc5dfa81b47e8c886a976bd580c795931c8b508
Merge: 61f668a 0a1be4e
Author: Akira TAGOH <akira at tagoh.org>
Date:   Thu Jun 12 12:15:03 2025 +0000

    Merge branch 'issues/464' into 'main'
    
    Fix a crash with broken cache
    
    Closes #464
    
    See merge request fontconfig/fontconfig!426

commit 0a1be4e86fa69b14527d5fd01e44b089293f6d00
Author: Akira TAGOH <akira at tagoh.org>
Date:   Thu Jun 12 17:57:05 2025 +0900

    ci: cleanup builddir

diff --git a/.gitlab-ci/build.sh b/.gitlab-ci/build.sh
index 0cf6ae9..4c1e2f5 100755
--- a/.gitlab-ci/build.sh
+++ b/.gitlab-ci/build.sh
@@ -221,7 +221,7 @@ elif [ x"$buildsys" == "xmeson" ]; then
     fi
     buildopt+=(--default-library=$type)
     if [ $clean_build -eq 1 ]; then
-        rm -rf $BUILDDIR || :
+        rm -rf "$BUILDDIR" "$PREFIX" || :
     fi
     TASK="meson setup"
     meson setup --prefix="$PREFIX" -D${subprojectname}nls=enabled -D${subprojectname}cache-build=disabled -D${subprojectname}iconv=enabled ${buildopt[*]} "$BUILDDIR" 2>&1 | tee /tmp/fc-build.log
commit 135b4a798c867fe962abe2f6071a78a7adbcb289
Author: Akira TAGOH <akira at tagoh.org>
Date:   Wed Jun 11 22:11:28 2025 +0900

    Fix a crash with broken cache
    
    Check offsets in a cache a bit more strictly
    to detect a broken cache.
    
    Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/464
    
    Changelog: fixed

diff --git a/fc-fontations/meson.build b/fc-fontations/meson.build
index 9a9ae70..5c483f7 100644
--- a/fc-fontations/meson.build
+++ b/fc-fontations/meson.build
@@ -6,7 +6,7 @@ if (fontations.enabled())
   generated_fontconfig = rust.bindgen(
     input : fontconfig_h,
     output : 'fontconfig.rs',
-    include_directories : [ '../' ],
+    include_directories : incbase,
     args : [
       '--merge-extern-blocks',
       '--allowlist-item=(FcCharSet.*|FC_(SLANT|WEIGHT|WIDTH)_.*|FcFontSet(Add|Create|Destroy).*|FcLangSet(Create|Destroy|Copy|Add|HasLang)|FcWeightFromOpenType.*|FC_DUAL|FC_MONO)',
@@ -20,9 +20,9 @@ if (fontations.enabled())
   )
 
   generated_fcint = rust.bindgen(
-    input : '../src/fcint.h',
+    input : ['../src/fcint.h', fclang_h],
     output : 'fcint.rs',
-    include_directories : [ '../' ],
+    include_directories : incbase,
     args : [
       '--merge-extern-blocks',
       '--allowlist-item=(FcPattern.*|FcRange.*|FC_.*_OBJECT|FcCharSet.*|FcFreeTypeLangSet)',
@@ -44,8 +44,8 @@ if (fontations.enabled())
 
   fontations_query_lib = static_library(
     'fc_fontations_query',
-    include_directories : [ '../', '../fontconfig' ],
-    sources: ['../src/fcfontations.c', fcstdint_h, alias_headers],
+    include_directories : incbase,
+    sources: ['../src/fcfontations.c', fcstdint_h, fclang_h, alias_headers],
   )
 
   fc_fontations = static_library(
diff --git a/meson.build b/meson.build
index 14c2cea..0fb3586 100644
--- a/meson.build
+++ b/meson.build
@@ -178,7 +178,7 @@ add_project_arguments('-DHAVE_CONFIG_H', language: 'c')
 c_args = []
 
 deps = [freetype_dep, xml_dep]
-incbase = include_directories('.')
+incbase = include_directories('.', 'fc-lang')
 
 # For compatibility to autoconf (regardless of the usage in fontconfig)
 conf.set_quoted('PACKAGE_NAME', meson.project_name())
diff --git a/src/Makefile.am b/src/Makefile.am
index 1811e56..16662e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -74,6 +74,7 @@ AM_CPPFLAGS = 						\
 	-I$(top_builddir)				\
 	-I$(top_srcdir)					\
 	-I$(top_srcdir)/src				\
+	-I$(top_builddir)/fc-lang			\
 	$(FREETYPE_CFLAGS)				\
 	$(ICONV_CFLAGS)					\
 	$(LIBXML2_CFLAGS)				\
diff --git a/src/fccache.c b/src/fccache.c
index c63976e..15791e3 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -850,10 +850,13 @@ FcCacheOffsetsValid (FcCache *cache)
 	    return FcFalse;
 
 	for (i = 0; i < fs->nfont; i++) {
-	    FcPattern     *font = FcFontSetFont (fs, i);
-	    FcPatternElt  *e;
-	    FcValueListPtr l;
-	    char          *last_offset;
+	    FcPattern       *font = FcFontSetFont (fs, i);
+	    FcPatternElt    *e;
+	    FcValueListPtr   l;
+	    char            *last_offset;
+	    const FcLangSet *ls;
+	    const FcRange   *r;
+	    const FcChar8   *s;
 
 	    if ((char *)font < base ||
 	        (char *)font > end - sizeof (FcFontSet) ||
@@ -873,6 +876,73 @@ FcCacheOffsetsValid (FcCache *cache)
 		    if ((char *)l < last_offset || (char *)l > end - sizeof (*l) ||
 		        (l->next != NULL && !FcIsEncodedOffset (l->next)))
 			return FcFalse;
+		    switch (l->value.type) {
+		    case FcTypeVoid:
+		    case FcTypeInteger:
+		    case FcTypeDouble:
+		    case FcTypeBool:
+		    case FcTypeMatrix:
+		    case FcTypeFTFace:
+			break; /* nop */
+		    case FcTypeString:
+			s = FcValueString (&l->value);
+			if ((intptr_t)s < (intptr_t)&e[j] ||
+			    (intptr_t)&l->value > (intptr_t)end - sizeof (*l) ||
+			    !FcIsEncodedOffset (l->value.u.s)) {
+			    if (FcDebug() & FC_DBG_CACHE) {
+				fprintf (stderr, "Fontconfig warning: invalid cache: broken string pointer\n");
+			    }
+			    return FcFalse;
+			}
+			break;
+		    case FcTypeCharSet:
+			/* FcCharSet might be re-used by FcCharSetFindFrozen
+			 * which would means a pointer might be out of Elts
+			 */
+			if ((intptr_t)&l->value > (intptr_t)end - sizeof (*l) ||
+			    !FcIsEncodedOffset (l->value.u.c)) {
+			    if (FcDebug() & FC_DBG_CACHE) {
+				fprintf (stderr, "Fontconfig warning: invalid cache: broken charset\n");
+			    }
+			    return FcFalse;
+			}
+			break;
+		    case FcTypeLangSet:
+			ls = FcValueLangSet (&l->value);
+			if ((intptr_t)ls < (intptr_t)&e[j] ||
+			    (intptr_t)&l->value > (intptr_t)end - sizeof (*l) ||
+			    !FcIsEncodedOffset (l->value.u.l)) {
+			    if (FcDebug() & FC_DBG_CACHE) {
+				fprintf (stderr, "Fontconfig warning: invalid cache: broken langset\n");
+			    }
+			    return FcFalse;
+			}
+			/* ls->extra isn't serialized. it must be null */
+			if (ls->extra != NULL) {
+			    if (FcDebug() & FC_DBG_CACHE) {
+				fprintf (stderr, "Fontconfig warning: invalid cache: broken langset\n");
+			    }
+			    return FcFalse;
+			}
+			break;
+		    case FcTypeRange:
+			r = FcValueRange (&l->value);
+			if ((intptr_t)r < (intptr_t)&e[j] ||
+			    (intptr_t)&l->value > (intptr_t)end - sizeof (*l) ||
+			    !FcIsEncodedOffset (l->value.u.r)) {
+			    if (FcDebug() & FC_DBG_CACHE) {
+				fprintf (stderr, "Fontconfig warning: invalid cache: broken range\n");
+			    }
+			    return FcFalse;
+			}
+			break;
+		    default:
+			/* just ignore unknown object type for upper-compatible in the future */
+			if (FcDebug() & FC_DBG_CACHEV) {
+			    fprintf (stderr, "Fontconfig warning: invalid cache: unknown object type in pattern: %d\n", l->value.type);
+			}
+			break;
+		    }
 		    last_offset = (char *)l + 1;
 		}
 	    }
diff --git a/src/fcint.h b/src/fcint.h
index 67a1604..195f558 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -1059,6 +1059,24 @@ void
 FcRuleDestroy (FcRule *rule);
 
 /* fclang.c */
+typedef struct {
+    const FcChar8   lang[16];
+    const FcCharSet charset;
+} FcLangCharSet;
+
+typedef struct {
+    int begin;
+    int end;
+} FcLangCharSetRange;
+
+#include "fclang.h"
+
+struct _FcLangSet {
+    FcStrSet *extra;
+    FcChar32  map_size;
+    FcChar32  map[NUM_LANG_SET_MAP];
+};
+
 FcPrivate FcLangSet *
 FcFreeTypeLangSet (const FcCharSet *charset,
                    const FcChar8   *exclusiveLang);
diff --git a/src/fclang.c b/src/fclang.c
index acd6ff2..28038d2 100644
--- a/src/fclang.c
+++ b/src/fclang.c
@@ -28,18 +28,6 @@
 
 /* Objects MT-safe for readonly access. */
 
-typedef struct {
-    const FcChar8   lang[16];
-    const FcCharSet charset;
-} FcLangCharSet;
-
-typedef struct {
-    int begin;
-    int end;
-} FcLangCharSetRange;
-
-#include "../fc-lang/fclang.h"
-
 /*
  * Keep Han languages separated by eliminating languages
  * that the codePageRange bits says aren't supported
@@ -57,12 +45,6 @@ static const struct {
 
 #define NUM_CODE_PAGE_RANGE (int)(sizeof FcCodePageRange / sizeof FcCodePageRange[0])
 
-struct _FcLangSet {
-    FcStrSet *extra;
-    FcChar32  map_size;
-    FcChar32  map[NUM_LANG_SET_MAP];
-};
-
 static int
 FcLangSetIndex (const FcChar8 *lang);
 
diff --git a/src/meson.build b/src/meson.build
index 1fa7fe1..bf5a781 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -9,7 +9,7 @@ endif
 # Factor our pattern manipulation code into its own library
 # to break the depedency cycle:
 # FontConfig pattern handling - Fontations code - FontConfig.
-pattern_sources = [ 'fcpat.c', fcstdint_h.to_list() ]
+pattern_sources = [ 'fcpat.c', fcstdint_h, fclang_h ]
 pattern_lib = static_library('patternlib_internal',
                                     pattern_sources,
                                     include_directories: incbase,
@@ -63,7 +63,7 @@ fcobjshash_h = custom_target('fcobjshash.h',
   command: [gperf, '--pic', '-m', '100', '@INPUT@', '--output-file', '@OUTPUT@']
 )
 
-lib_fontconfig_sources = [fc_sources, alias_headers, ft_alias_headers, fclang_h, fccase_h, fcobjshash_h, fcstdint_h]
+lib_fontconfig_sources = [fc_sources, alias_headers, ft_alias_headers, fccase_h, fclang_h, fcobjshash_h, fcstdint_h]
 lib_fontconfig_kwargs = {
   'include_directories': incbase,
   'dependencies': [deps, math_dep],
diff --git a/test/meson.build b/test/meson.build
index 05a6932..50e1906 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -59,7 +59,7 @@ foreach test_data : tests + tests_not_parallel
 
   test_name = fname.split('.')[0].underscorify()
 
-  exe = executable(test_name, fname, fcstdint_h,
+  exe = executable(test_name, fname, fcstdint_h, fclang_h,
     c_args: c_args + extra_c_args,
     include_directories: [incbase] + extra_incdir,
     link_with: link_with_libs,


More information about the Fontconfig mailing list