diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.gitignore b/.gitignore index 03adcba..c15e946 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ fontforge_full-20100501.tar.bz2 /fontforge-20200314.tar.gz /fontforge-20201107.tar.gz /fontforge-20230101.tar.gz +/fontforge-20251009.tar.gz diff --git a/Fix_Splinefont_shell_invocation.patch b/Fix_Splinefont_shell_invocation.patch new file mode 100644 index 0000000..1d75f6c --- /dev/null +++ b/Fix_Splinefont_shell_invocation.patch @@ -0,0 +1,178 @@ +From a64099931ea004a08e074b08ad0984d92c25daa2 Mon Sep 17 00:00:00 2001 +From: Peter Kydas +Date: Tue, 6 Feb 2024 10:23:36 +1100 +Subject: [PATCH] fix splinefont shell command injection + +--- + fontforge/splinefont.c | 125 +++++++++++++++++++++++++++++------------ + 1 file changed, 90 insertions(+), 35 deletions(-) + +diff --git a/fontforge/splinefont.c b/fontforge/splinefont.c +index 239fdc035b..647daee109 100644 +--- a/fontforge/splinefont.c ++++ b/fontforge/splinefont.c +@@ -788,11 +788,14 @@ return( name ); + + char *Unarchive(char *name, char **_archivedir) { + char *dir = getenv("TMPDIR"); +- char *pt, *archivedir, *listfile, *listcommand, *unarchivecmd, *desiredfile; ++ char *pt, *archivedir, *listfile, *desiredfile; + char *finalfile; + int i; + int doall=false; + static int cnt=0; ++ gchar *command[5]; ++ gchar *stdoutresponse = NULL; ++ gchar *stderrresponse = NULL; + + *_archivedir = NULL; + +@@ -827,18 +830,30 @@ return( NULL ); + listfile = malloc(strlen(archivedir)+strlen("/" TOC_NAME)+1); + sprintf( listfile, "%s/" TOC_NAME, archivedir ); + +- listcommand = malloc( strlen(archivers[i].unarchive) + 1 + +- strlen( archivers[i].listargs) + 1 + +- strlen( name ) + 3 + +- strlen( listfile ) +4 ); +- sprintf( listcommand, "%s %s %s > %s", archivers[i].unarchive, +- archivers[i].listargs, name, listfile ); +- if ( system(listcommand)!=0 ) { +- free(listcommand); free(listfile); +- ArchiveCleanup(archivedir); +-return( NULL ); +- } +- free(listcommand); ++ command[0] = archivers[i].unarchive; ++ command[1] = archivers[i].listargs; ++ command[2] = name; ++ command[3] = NULL; // command args need to be NULL-terminated ++ ++ if ( g_spawn_sync( ++ NULL, ++ command, ++ NULL, ++ G_SPAWN_SEARCH_PATH, ++ NULL, ++ NULL, ++ &stdoutresponse, ++ &stderrresponse, ++ NULL, ++ NULL ++ ) == FALSE) { // did not successfully execute ++ ArchiveCleanup(archivedir); ++ return( NULL ); ++ } ++ // Write out the listfile to be read in later ++ FILE *fp = fopen(listfile, "wb"); ++ fwrite(stdoutresponse, strlen(stdoutresponse), 1, fp); ++ fclose(fp); + + desiredfile = ArchiveParseTOC(listfile, archivers[i].ars, &doall); + free(listfile); +@@ -847,22 +862,28 @@ return( NULL ); + return( NULL ); + } + +- /* I tried sending everything to stdout, but that doesn't work if the */ +- /* output is a directory file (ufo, sfdir) */ +- unarchivecmd = malloc( strlen(archivers[i].unarchive) + 1 + +- strlen( archivers[i].listargs) + 1 + +- strlen( name ) + 1 + +- strlen( desiredfile ) + 3 + +- strlen( archivedir ) + 30 ); +- sprintf( unarchivecmd, "( cd %s ; %s %s %s %s ) > /dev/null", archivedir, +- archivers[i].unarchive, +- archivers[i].extractargs, name, doall ? "" : desiredfile ); +- if ( system(unarchivecmd)!=0 ) { +- free(unarchivecmd); free(desiredfile); +- ArchiveCleanup(archivedir); +-return( NULL ); ++ command[0] = archivers[i].unarchive; ++ command[1] = archivers[i].extractargs; ++ command[2] = name; ++ command[3] = doall ? "" : desiredfile; ++ command[4] = NULL; ++ ++ if ( g_spawn_sync( ++ (gchar*)archivedir, ++ command, ++ NULL, ++ G_SPAWN_SEARCH_PATH, ++ NULL, ++ NULL, ++ &stdoutresponse, ++ &stderrresponse, ++ NULL, ++ NULL ++ ) == FALSE) { // did not successfully execute ++ free(desiredfile); ++ ArchiveCleanup(archivedir); ++ return( NULL ); + } +- free(unarchivecmd); + + finalfile = malloc( strlen(archivedir) + 1 + strlen(desiredfile) + 1); + sprintf( finalfile, "%s/%s", archivedir, desiredfile ); +@@ -885,20 +906,54 @@ struct compressors compressors[] = { + + char *Decompress(char *name, int compression) { + char *dir = getenv("TMPDIR"); +- char buf[1500]; + char *tmpfn; +- ++ gchar *command[4]; ++ gint stdout_pipe; ++ gchar buffer[4096]; ++ gssize bytes_read; ++ GByteArray *binary_data = g_byte_array_new(); ++ + if ( dir==NULL ) dir = P_tmpdir; + tmpfn = malloc(strlen(dir)+strlen(GFileNameTail(name))+2); + strcpy(tmpfn,dir); + strcat(tmpfn,"/"); + strcat(tmpfn,GFileNameTail(name)); + *strrchr(tmpfn,'.') = '\0'; +- snprintf( buf, sizeof(buf), "%s < %s > %s", compressors[compression].decomp, name, tmpfn ); +- if ( system(buf)==0 ) +-return( tmpfn ); +- free(tmpfn); +-return( NULL ); ++ ++ command[0] = compressors[compression].decomp; ++ command[1] = "-c"; ++ command[2] = name; ++ command[3] = NULL; ++ ++ // Have to use async because g_spawn_sync doesn't handle nul-bytes in the output (which happens with binary data) ++ if (g_spawn_async_with_pipes( ++ NULL, ++ command, ++ NULL, ++ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ &stdout_pipe, ++ NULL, ++ NULL) == FALSE) { ++ //command has failed ++ return( NULL ); ++ } ++ ++ // Read binary data from pipe and output to file ++ while ((bytes_read = read(stdout_pipe, buffer, sizeof(buffer))) > 0) { ++ g_byte_array_append(binary_data, (guint8 *)buffer, bytes_read); ++ } ++ close(stdout_pipe); ++ ++ FILE *fp = fopen(tmpfn, "wb"); ++ fwrite(binary_data->data, sizeof(gchar), binary_data->len, fp); ++ fclose(fp); ++ g_byte_array_free(binary_data, TRUE); ++ ++ return(tmpfn); + } + + static char *ForceFileToHaveName(FILE *file, char *exten) { diff --git a/fontforge.spec b/fontforge.spec index 2b63d1d..846dfdd 100644 --- a/fontforge.spec +++ b/fontforge.spec @@ -1,15 +1,13 @@ %global gettext_package FontForge Name: fontforge -Version: 20230101 -Release: 8%{?dist} +Version: 20251009 +Release: 1%{?dist} Summary: Outline and bitmap font editor License: GPL-3.0-or-later URL: http://fontforge.github.io/ Source0: https://github.com/fontforge/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz -# Fix translations with gettext-0.22, https://github.com/fontforge/fontforge/pull/5257 -Patch0: 0001-Fix-errors-in-French-and-Italian-translations.patch Requires: xdg-utils Requires: (autotrace or potrace) @@ -40,6 +38,8 @@ BuildRequires: shared-mime-info BuildRequires: gtk3-devel BuildRequires: python3-sphinx BuildRequires: make +# 20151009 version requires below +BuildRequires: gtkmm3.0-devel %py_provides python3-fontforge %py_provides python3-psMat @@ -68,17 +68,13 @@ This package contains documentation files for %{name}. %prep -%setup -q -%patch -P 0 -p1 - -# Remove tests that requires Internet access -sed -i '45d;82d;101d;127d' tests/CMakeLists.txt - +%autosetup %build export CFLAGS="%{optflags} -fno-strict-aliasing" %cmake -DCMAKE_BUILD_TYPE=Release \ - -DENABLE_WOFF2=ON + -DENABLE_WOFF2=ON \ + -DPYHOOK_INSTALL_DIR=%{python3_sitearch} %cmake_build %install @@ -100,9 +96,7 @@ appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/*.appdata.xml %find_lang %{gettext_package} %check -pushd %{__cmake_builddir} -make check -popd +%ctest %files -f %{gettext_package}.lang %doc AUTHORS @@ -125,6 +119,41 @@ popd %doc %{_pkgdocdir} %changelog +* Fri Oct 10 2025 Parag Nemade - 20251009-1 +- Update to 20251009 version (#2402960) +- Remove upstream released patches +- Add new BR: gtkmm3.0-devel + +* Wed Jul 23 2025 Fedora Release Engineering - 20230101-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Thu Jul 17 2025 Parag Nemade - 20230101-17 +- Update for https://fedoraproject.org/wiki/Changes/CMake_ninja_default (rh#2381004) + +* Tue Jun 03 2025 Python Maint - 20230101-16 +- Rebuilt for Python 3.14 + +* Thu Jan 16 2025 Fedora Release Engineering - 20230101-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Wed Jul 17 2024 Fedora Release Engineering - 20230101-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Fri Jun 14 2024 Gwyn Ciesla - 20230101-13 +- Patch for Python 3.13 + +* Fri Jun 07 2024 Python Maint - 20230101-12 +- Rebuilt for Python 3.13 + +* Wed Feb 28 2024 Parag Nemade - 20230101-11 +- Resolves: CVE-2024-25081 and CVE-2024-25082 + +* Wed Jan 24 2024 Fedora Release Engineering - 20230101-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 20230101-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Thu Aug 10 2023 Yaakov Selkowitz - 20230101-8 - Drop unused libuninameslist dependency diff --git a/plans/fontforge.fmf b/plans/fontforge.fmf new file mode 100644 index 0000000..c1627f9 --- /dev/null +++ b/plans/fontforge.fmf @@ -0,0 +1,5 @@ +summary: Basic smoke test +discover: + how: fmf +execute: + how: tmt diff --git a/pyconfig.patch b/pyconfig.patch new file mode 100644 index 0000000..cfd90f4 --- /dev/null +++ b/pyconfig.patch @@ -0,0 +1,24 @@ +--- pycontrib/FontCompare/setup.py~ 2022-12-31 23:25:21.000000000 -0600 ++++ pycontrib/FontCompare/setup.py 2024-06-14 15:14:14.119920623 -0500 +@@ -15,7 +15,6 @@ + along with this program. If not, see . + """ + #!/usr/bin/env python +-from distutils.core import setup + from setuptools import setup + setup(name='Font Compare', + version='1.0', +--- fontforge/python.c~ 2022-12-31 23:25:21.000000000 -0600 ++++ fontforge/python.c 2024-06-14 15:38:41.397897757 -0500 +@@ -19633,7 +19633,10 @@ + if ( saved_progname ) + free(saved_progname); + saved_progname = copy_to_wide_string(progname); +- Py_SetProgramName(saved_progname); ++ PyStatus status; ++ PyConfig config; ++ PyConfig_InitPythonConfig(&config); ++ status = PyConfig_SetString(&config, &config.program_name, saved_progname); + } + + static wchar_t ** copy_argv(char *arg0, int argc ,char **argv) { diff --git a/sources b/sources index b0ab3ee..3c609cb 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (fontforge-20230101.tar.gz) = 67c21f7e55a78097ef7d7d9abac3add2017400015a6a9dfd56674d933bdba963cb6c4e631ae066026fe1862298d60dd968dec61a9bbee7253dd2f7d105655178 +SHA512 (fontforge-20251009.tar.gz) = 2923c54e10585551c93102d8b7a389c9de3c629c1676fc8c576c9b9c3f1f6fe28f7a1e39fd5a57ab7eeadf0b17d722bf439ca94f0a788ceab6993e1a93ea7d5f diff --git a/tests/scripts/generate-font.py b/tests/generate-font.py similarity index 100% rename from tests/scripts/generate-font.py rename to tests/generate-font.py diff --git a/tests/scripts/generate-sfd.pe b/tests/generate-sfd.pe similarity index 100% rename from tests/scripts/generate-sfd.pe rename to tests/generate-sfd.pe diff --git a/tests/scripts/generate-ttf.pe b/tests/generate-ttf.pe similarity index 100% rename from tests/scripts/generate-ttf.pe rename to tests/generate-ttf.pe diff --git a/tests/scripts/get-font-metadata.py b/tests/get-font-metadata.py similarity index 100% rename from tests/scripts/get-font-metadata.py rename to tests/get-font-metadata.py diff --git a/tests/main.fmf b/tests/main.fmf new file mode 100644 index 0000000..542903b --- /dev/null +++ b/tests/main.fmf @@ -0,0 +1,5 @@ +require: +- fontforge +test: bash ./run_tests.sh +framework: shell + diff --git a/tests/scripts/run_tests.sh b/tests/run_tests.sh old mode 100644 new mode 100755 similarity index 100% rename from tests/scripts/run_tests.sh rename to tests/run_tests.sh diff --git a/tests/runtests.sh b/tests/runtests.sh new file mode 100755 index 0000000..a94d8f5 --- /dev/null +++ b/tests/runtests.sh @@ -0,0 +1,47 @@ +#!/bin/bash +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +NAME=fontforge + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${NAME} + rlAssertRpm ${NAME}-devel + rlShowPackageVersion ${NAME} + rlRun -t -l "VERSION=$(rpm -q ${NAME} --queryformat='%{version}')" 0 "Get VERSION" + FEDORA_VERSION=$(rlGetDistroRelease) + rlLog "FEDORA_VERSION=${DISTRO_RELEASE}" + rlRun "tmp=\$(mktemp -d)" 0 "Create tmp directory" + rlRun "pushd $tmp" + rlFetchSrcForInstalled "${NAME}" + rlRun "rpm --define '_topdir $tmp' -i *src.rpm" + rlRun -t -l "mkdir BUILD" 0 "Creating BUILD directory" + rlRun -t -l "rpmbuild --noclean --nodeps --define '_topdir $tmp' -bp $tmp/SPECS/*spec" + if [ -d BUILD/${NAME}-${VERSION}-build ]; then + rlRun -t -l "pushd BUILD/${NAME}-${VERSION}-build/${NAME}-${VERSION}" + else + rlRun -t -l "pushd BUILD/${NAME}-${VERSION}" + fi + rlRun "set -o pipefail" + rlRun "NOCONFIGURE=1 ./autogen.sh" + rlRun "./configure --disable-static --with-graphite2 --with-gobject --enable-introspection" + rlRun "make check" + rlRun "retval=$?" + rlRun "echo $retval" + rlPhaseEnd + + rlPhaseStartTest + rlRun -t -l "INSTALLED_VERSION=$(hb-info --version|awk 'NR==1 {print $3}')" \ + 0 "Get installed version" + rlAssertEquals "versions should be equal" "${VERSION}" "${INSTALLED_VERSION}" + rlGetTestState + rlLog "Number of failed asserts so far: ${ECODE}" + rlRun "popd" 0 + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $tmp" 0 "Remove tmp directory" + rlPhaseEnd +rlJournalEnd + diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index aaf3946..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,9 +0,0 @@ -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - tests: - - simple: - dir: scripts/ - run: ./run_tests.sh