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