Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
f4814d3
Fix iconv(3) arguments (#5637)
0-wiz-0 Oct 10, 2025
afa4690
Remove `gi` field from charview (#5640)
valadaptive Oct 11, 2025
fe07b94
Differentiate Supplementary PUA planes by name (#5650)
iorsh Oct 15, 2025
fb4a9e2
Fix restrict violation (#5651)
f380cedric Oct 17, 2025
e52bc1e
Fix script / language application in HarfBuzz (#5658)
iorsh Oct 22, 2025
512b966
Update CI to MacOS 14 image (#5642)
iorsh Oct 31, 2025
5a69313
Fix Python documentation errors (#5646)
iorsh Nov 1, 2025
0de8675
OtfFeatName for `cv??` (#5662)
MihailJP Nov 2, 2025
9d793fe
Fix crash issue in allmarkglyphs (#5668)
MihailJP Nov 3, 2025
77b1b14
Fix UFO crash for empty contours (#5645)
iorsh Nov 4, 2025
5df9f18
Document `no-mac-names` flag for font.generate (#5669)
MihailJP Nov 5, 2025
46dc374
Fix crash in Metrics View (#5647)
iorsh Nov 6, 2025
7466cf3
Document missing python module members (#5657)
chanicpanic Nov 8, 2025
0ff1f20
Sort entries in "Language List" dialog and allow search (#5648)
iorsh Nov 9, 2025
d6c0701
FindMatchingHVEdge: report problematic glyph (#5087) (#5675)
tuffnatty Nov 10, 2025
f450725
Document mark set parameter for font.addLookup() Python API (#5674)
tuffnatty Nov 11, 2025
6a0be00
Fix UI font on Windows for CJK locales (#5663)
iorsh Nov 12, 2025
74b7969
Python API: Add font.markSets. Add tests for font.markClasses and fon…
tuffnatty Nov 13, 2025
ce3693d
Fix flags parameter of font.generateTTC (#5677)
MihailJP Nov 14, 2025
aca4f52
Metrics view: Fix crash on Up/Down keypress while in the feature list…
tuffnatty Nov 17, 2025
d063483
Cleanup, fix UI font for CJK when loading resource (#5679)
tuffnatty Nov 18, 2025
fbc4114
Use importlib in plugin manager (#5643)
iorsh Nov 22, 2025
c6c7bd2
Implement `with` statement for Python font object (#5694)
iorsh Nov 23, 2025
9d119ca
Ignore bit 1 of head.flags for CFF fonts (#5698)
khaledhosny Dec 1, 2025
0c9d0ca
Fix Python config initialization (#5699)
iorsh Dec 2, 2025
85026c2
Add dependency missing in INSTALL.md (#5701)
Finii Dec 7, 2025
aedb8f2
tottf: Fix hmtx table (all widths zero) for monospaced fonts (#5702)
Finii Dec 8, 2025
dfc1598
Fix SplineCharCopy() for Python objects, SplineChar::comment (#5696)
iorsh Dec 10, 2025
438679c
Remove X11 backend options from CLI and from documentation (#5690)
iorsh Dec 11, 2025
ecf2161
Documentation fixes (#5687)
iorsh Dec 13, 2025
9565a27
At UFO export, use family name for styleMapFamilyName (#5672)
MihailJP Dec 14, 2025
3a960a4
Fix glyph.codepoint attribute (#5709)
iorsh Dec 22, 2025
7d67700
Fix CVE-2025-15279: Heap buffer overflow in BMP RLE decompression (#5…
ahmetfurkankavraz Jan 8, 2026
7195402
Fix CVE-2025-15275: Heap buffer overflow in SFD image parsing (#5721)
ahmetfurkankavraz Jan 9, 2026
6aea6db
Fix CVE-2025-15269: Use-after-free in SFD ligature parsing (#5722)
ahmetfurkankavraz Jan 10, 2026
e9474d0
Fix Python hooks, test_font_hooks.py (#5724)
iorsh Jan 11, 2026
720ea95
Fix CVE-2025-15279: Move bounds check inside cnt >= 3 block (#5723)
ahmetfurkankavraz Jan 12, 2026
0df57ac
Fix crash for content over 32767 characters in GDraw multiline text f…
iorsh Jan 13, 2026
7bd768a
Add CMake target to autoformat source files (#5730)
iorsh Jan 16, 2026
dfe5c80
Fix multiple crashes in Multiple Masters (#5733)
iorsh Jan 19, 2026
7f71b51
Improve bulk_test.sh script (#5714)
iorsh Jan 23, 2026
d6664db
Fix "FONT_ASCENT", "FONT_DESCENT", "SPACING" BDF properties (#5710)
iorsh Jan 26, 2026
6338c36
Fix glyph name and Unicode value deduction for SVG fonts (#5667)
iorsh Jan 27, 2026
6781d61
Apply width when copying chars in bitmap-only font (#5711)
iorsh Jan 28, 2026
42a35cb
Fix and disallow duplicate-encoded glyphs (#5715)
iorsh Jan 29, 2026
d01333a
Fix CVE-2025-15270: Heap buffer overflow in SFD kern class parsing (#…
ahmetfurkankavraz Jan 31, 2026
cb44343
Fix crashes on importing Mac-style dfont/NFNT bitmap fonts with some …
robhagemans Feb 1, 2026
c70dedf
[Python] make generateTtc use the active layer by default (#5221)
IsaacOscar Feb 2, 2026
41b0c97
Simplify fake encoding trick in Metrics View (#5736)
iorsh Feb 3, 2026
4a69512
Quickfix a collision between ttf_flags and ps_flags (#5678) (#5681)
tuffnatty Feb 6, 2026
b2789ba
Make fontforge module dependent on shapers (#5749)
iorsh Feb 9, 2026
a4533e9
Fix memory allocation in utf8toutf7_copy() (#5745)
iorsh Feb 14, 2026
763b8fc
Fix crash in LoadPluginMetadata when distribution not found (#5755)
skef Feb 16, 2026
716d3f0
Fix import of multiple images in UI (#5744)
iorsh Feb 17, 2026
3206447
Fix SFGenerateFont() for Mac family flags (#5757)
iorsh Feb 18, 2026
f118600
Support PyPI python modules, including for Windows (#5750)
skef Feb 21, 2026
200a1d5
GTK-based "Find Problems" dialog (#5682)
iorsh Feb 27, 2026
e39bd58
Put app mids in include files (#5763)
skef Feb 27, 2026
ec1c14c
Fix source generation for Gettext (#5764)
iorsh Feb 28, 2026
c977671
GTK-based "Bitmap Strikes" dialog (#5708)
iorsh Feb 28, 2026
85db3ac
Fix Build Accented Glyph when only spacing accent exists (#5767)
skef Mar 2, 2026
08f2728
Don't apply DESTDIR twice when installing libraries (#5771)
atsampson Mar 7, 2026
aa18743
Fix opening of compressed font files (#5774)
iorsh Mar 10, 2026
dd54964
Modernize default bookmarks per OS (#5772)
iorsh Mar 11, 2026
570ff8e
Fix references when exporting SVG without flip transformation (#5773)
iorsh Mar 12, 2026
c2fd2df
GTK-based generic property dialogs (#5768)
iorsh Mar 22, 2026
96bedae
Merge fontforgebuilds into main repository (#5781)
skef Mar 26, 2026
5ce04fd
Fix some compilation warnings (#5777)
iorsh Mar 28, 2026
475818b
Reject negative bitmap sizes on validation (#5780)
iorsh Mar 29, 2026
5ceb680
Discard \r characters in pickled data (#5787)
iorsh Mar 31, 2026
a01d2eb
Windows build fixes (#5789)
iorsh Apr 1, 2026
872c820
Update CI actions, silence homebrew warnings (#5803)
rettinghaus Apr 20, 2026
1f5a771
OOB Write in pdf_getcmap() (#5804)
iorsh Apr 21, 2026
e9156ac
Initialize legacy resources before converting them to CSS (#5792)
iorsh May 3, 2026
63b04fa
Automatic Windows changelog from latest git commits (#5794)
iorsh May 4, 2026
fd011a6
Fix emsize derivation for PostScript fonts (#5795)
iorsh May 5, 2026
e5f110c
Fix buffer overflow in SCDefWidthVal() (#5798)
iorsh May 6, 2026
cff8b84
Fix segfault in Python `font.italicize` function (#5818)
gucci-on-fleek May 22, 2026
8a7d179
Conditionally use Python3::Module target linking in CMake (#5819)
justdan96 May 23, 2026
b3ae3ae
Expose the `xheight_percent` parameter to Python in font.italicize() …
gucci-on-fleek May 24, 2026
99e37fc
Fix crash on GTK initialization (#5823)
iorsh May 26, 2026
e59ffca
Fix pyhook initialization (#5822)
iorsh May 28, 2026
0bb1a2b
Allow multiple contextual subtable rules (#5826)
basil May 30, 2026
9bf910e
Fix issues in "Find Problems" (#5793)
iorsh Jun 6, 2026
28e71fb
GTK-based "Show Histogram" dialog (#5796)
iorsh Jun 7, 2026
0b8dcda
Fix double-count of a contour's first point in cv_ptlistcheck (#5835)
skef Jun 9, 2026
665d2c0
Add script GlyphAlignment.py to pycontrib (#5827)
unbeebnu Jun 10, 2026
416e773
macOS: ad-hoc code sign the app bundle, with a Developer ID path (#5834)
skef Jun 11, 2026
b5e2bb1
Build Mac binary for Intel and for ARM64 (#5838)
iorsh Jun 14, 2026
f68a5dd
"Outline Window" Improved interactive scaling + docs (#5837)
erco77 Jun 17, 2026
02f4a37
fix pyhook install dir on Debian's posix_local (#5841)
nadalaba Jun 20, 2026
fc490c4
Rename ka_Ge locale to ka, update translations from Crowdin (#5843)
iorsh Jun 24, 2026
b050af9
defer install prefix evaluation
nadalaba Jun 26, 2026
a956328
fix: remove extra leading 'local/' when python < 3.10 too
nadalaba Jun 26, 2026
1cf96f7
fix: correct potfile generation for MSYS2 Ninja builds
nadalaba Jun 26, 2026
746b579
fix: use user-defined for build files on MSYS2
nadalaba Jun 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
40 changes: 14 additions & 26 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
image: Visual Studio 2019
image: Visual Studio 2022
platform:
- x64
branches:
Expand All @@ -10,27 +10,15 @@ environment:
MBASH: C:\msys64\usr\bin\sh -lc
MSYS2_FC_CACHE_SKIP: true
matrix:
- MSYSTEM: MINGW32
MBITS: 32
for:
-
branches:
only:
- /release\/.*/
environment:
global:
APPVEYOR_CONFIG_PROD: 1
matrix: # This extends the default, so 32 bit is still built
- MSYSTEM: MINGW64
MBITS: 64
- MSYSTEM: UCRT64
MBITS: 64

clone_depth: 10

#The cache is slightly slower than just downloading the files
#cache:
# - 'C:\msys64\var\cache\pacman\pkg'
install:
- git clone --depth=1 --branch=master-local https://github.com/fontforge/fontforgebuilds.git
- >-
move C:\msys64 C:\msys64_old &&
curl -kLo msys2.tar.xz https://github.com/msys2/msys2-installer/releases/download/nightly-x86_64/msys2-base-x86_64-latest.tar.xz &&
Expand All @@ -40,20 +28,20 @@ install:
- call %MBASH% "pacman -Syuu --noconfirm"
- taskkill /f /fi "MODULES eq msys-2.0.dll" || exit /b 0
- call %MBASH% "pacman -Suu --noconfirm"
- call %MBASH% "pacman -Suu --noconfirm"
- call %MBASH% "cd $APPVEYOR_BUILD_FOLDER/fontforgebuilds; exec 0</dev/null; ./ffbuild.sh --appveyor --depsonly"
- call %MBASH% "pacman -Suu --noconfirm"
- call %MBASH% "cd $APPVEYOR_BUILD_FOLDER/Packaging/win; exec 0</dev/null; BUILD_DIR=$TEMP/ffbuild ./ffbuild.sh --appveyor --depsonly"
build_script:
- call %MBASH% "cd $APPVEYOR_BUILD_FOLDER/fontforgebuilds; exec 0</dev/null; ./ffbuild.sh --appveyor"
- call %MBASH% "cd $APPVEYOR_BUILD_FOLDER/fontforgebuilds; exec 0</dev/null; FFPATH=`cygpath -m $APPVEYOR_BUILD_FOLDER` ./make-portable-package.sh appveyor"
- if "%APPVEYOR_REPO_BRANCH:~0,8%"=="release/" cd "%APPVEYOR_BUILD_FOLDER%/fontforgebuilds/fontforge-setup" && "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" -Qp fontforgesetup.iss
- call %MBASH% "cd $APPVEYOR_BUILD_FOLDER/Packaging/win; exec 0</dev/null; BUILD_DIR=$TEMP/ffbuild ./ffbuild.sh --appveyor"
- call %MBASH% "cd $APPVEYOR_BUILD_FOLDER/Packaging/win; exec 0</dev/null; BUILD_DIR=$TEMP/ffbuild FFPATH=`cygpath -m $APPVEYOR_BUILD_FOLDER` ./make-portable-package.sh appveyor"
- if "%APPVEYOR_REPO_BRANCH:~0,8%"=="release/" cd "%APPVEYOR_BUILD_FOLDER%/Packaging/win/setup" && "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" -Qp fontforgesetup.iss -DBUILD_DIR="%TEMP%\ffbuild"
test: off
artifacts:
- path: fontforgebuilds\*-appveyor.7z
name: FontForge $(MBITS)-bit build
- path: fontforgebuilds\*-debugging-symbols.7z
name: FontForge $(MBITS)-bit debugging symbols
- path: fontforgebuilds\fontforge-setup\*.exe
name: FontForge $(MBITS)-bit setup
- path: Packaging\win\*-appveyor.7z
name: FontForge 64-bit build
- path: Packaging\win\*-debugging-symbols.7z
name: FontForge 64-bit debugging symbols
- path: Packaging\win\setup\*.exe
name: FontForge 64-bit setup
#on_failure:
# - cat build/CMakeCache.txt || true
# - cat build/CMakeFiles/CMakeOutput.log || true
Expand Down
25 changes: 25 additions & 0 deletions .clang-files
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
inc/tag.hpp
inc/ffdir.h
inc/ffglib_compat.h
inc/ffprocess.h
inc/ffunistd.h
inc/l10n_text.hpp
fontforge/splinechar.h
fontforge/splinefont_enums.h
fontforge/std_maps.cpp
fontforge/std_maps.hpp
fontforge/ffglib_compat.cpp
fontforge/ffprocess.c
fontforge/glif_name_hash.cpp
fontforge/shapers/*.cpp
fontforge/shapers/*.hpp
fontforge/shapers/*.h
fontforgeexe/bitmapdlg.cpp
fontforgeexe/histograms.cpp
fontforgeexe/gtk/*.cpp
fontforgeexe/gtk/*.hpp
fontforgeexe/gtk/widgets/*.cpp
fontforgeexe/gtk/widgets/*.hpp
gutils/ffdir.cpp
gutils/gutils.cpp
tests/systestdriver.cpp
6 changes: 2 additions & 4 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
---
BasedOnStyle: Google
---
Language: Cpp
Standard: c++17
AccessModifierOffset: -3
Standard: c++17
IndentWidth: 4
AccessModifierOffset: -3
SpacesBeforeTrailingComments: 2
SortIncludes: false
IndentAccessModifiers: false
Expand Down
162 changes: 162 additions & 0 deletions .github/workflows/mac-signing-rehearsal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Manual rehearsal of the macOS Developer ID signing path, using a throwaway
# self-signed certificate generated on the runner.
#
# Purpose: exercise everything the real signing path does EXCEPT notarization,
# which a self-signed cert cannot do (Apple's notary service requires a genuine
# Developer ID Application certificate). In particular this validates the one
# thing the ad-hoc path can never test: that under the hardened runtime, the
# `disable-library-validation` entitlement actually lets FontForge's embedded
# Python interpreter load a third-party (foreign-signed) C extension.
#
# This workflow is workflow_dispatch only: it never runs on push and never
# produces a release artifact. The bundle it builds is SELF-SIGNED and must
# NOT be distributed.
name: macOS signing rehearsal (self-signed)

on:
workflow_dispatch:
inputs:
foreign_test_package:
description: 'PyPI package with a compiled C extension, used to test disable-library-validation under the hardened runtime'
type: string
default: cffi

jobs:
rehearsal:
runs-on: macos-14
steps:
- uses: actions/checkout@v6
with:
path: repo

# --- Mirror the normal mac build (deps + build) -----------------------
- name: Install dependencies
run: |
brew install cairo coreutils fontconfig gettext giflib gtk+3 gtkmm3 jpeg libpng libspiro libtiff libtool libuninameslist python@3 wget woff2 --quiet
PREFIX=$GITHUB_WORKSPACE/target
echo "PREFIX=$PREFIX" >> $GITHUB_ENV
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" >> $GITHUB_ENV
echo "PATH=/usr/local/opt/ruby/bin:/usr/local/opt/gettext/bin:$PATH" >> $GITHUB_ENV
echo "PYTHONPATH=$PREFIX" >> $GITHUB_ENV
- name: Build FontForge
working-directory: repo
run: |
FFCONFIG="-DCMAKE_INSTALL_PREFIX=$PREFIX -DENABLE_FONTFORGE_EXTRAS=ON -DCMAKE_FIND_ROOT_PATH=/usr/local/opt/gettext"
mkdir build && pushd build && cmake -GNinja $FFCONFIG .. && popd
ninja -C build install

# --- Generate + import a throwaway self-signed code-signing cert -------
# Use the system (LibreSSL) openssl so the PKCS#12 is readable by the
# macOS keychain without needing the `-legacy` flag.
- name: Generate and import self-signed certificate
run: |
WORK="$RUNNER_TEMP/selfsign"
mkdir -p "$WORK"
cat > "$WORK/cert.conf" <<'EOF'
[req]
distinguished_name = dn
x509_extensions = v3
prompt = no
[dn]
CN = FontForge Rehearsal Self-Signed
[v3]
basicConstraints = critical,CA:FALSE
keyUsage = critical,digitalSignature
extendedKeyUsage = critical,codeSigning
EOF
/usr/bin/openssl req -x509 -newkey rsa:2048 -nodes \
-keyout "$WORK/key.pem" -out "$WORK/cert.pem" \
-days 2 -config "$WORK/cert.conf"
/usr/bin/openssl pkcs12 -export \
-inkey "$WORK/key.pem" -in "$WORK/cert.pem" \
-out "$WORK/cert.p12" -passout pass:rehearsal \
-name "FontForge Rehearsal Self-Signed"

KEYCHAIN="$RUNNER_TEMP/rehearsal.keychain-db"
security create-keychain -p actions "$KEYCHAIN"
security set-keychain-settings -lut 3600 "$KEYCHAIN"
security unlock-keychain -p actions "$KEYCHAIN"
security import "$WORK/cert.p12" -k "$KEYCHAIN" -P rehearsal -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k actions "$KEYCHAIN"
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | tr -d '"')
security find-identity -v -p codesigning "$KEYCHAIN"

# Drive ffosxbuild.sh down its Developer ID branch (hardened runtime +
# entitlements). NOTE: we intentionally do NOT set any notary secrets,
# so notarization is correctly skipped -- self-signed cannot notarize.
echo "CODESIGN_IDENTITY=FontForge Rehearsal Self-Signed" >> "$GITHUB_ENV"

- name: Build App Bundle (hardened runtime, self-signed)
working-directory: repo/build
run: ninja macbundle

# --- Verify the signing we just rehearsed -----------------------------
- name: Verify signature and hardened runtime
working-directory: repo/build/osx
run: |
set -e
APP="$PWD/FontForge.app"
MAIN="$APP/Contents/Resources/opt/local/bin/fontforge"

echo "::group::codesign --verify (whole bundle)"
codesign --verify --strict --verbose=2 "$APP"
echo "::endgroup::"

echo "::group::Main executable signature (expect runtime flag + entitlements)"
codesign -dvvv "$MAIN" 2>&1 | grep -Ei 'Identifier|Signature|flags|TeamIdentifier' || true
codesign -d --entitlements :- "$MAIN" 2>&1 || true
echo "::endgroup::"

# Sanity: the hardened runtime flag must be present on the main exec.
if ! codesign -dvvv "$MAIN" 2>&1 | grep -q 'flags=.*runtime'; then
echo "ERROR: hardened runtime flag not set on main executable"
exit 1
fi

# Expected: spctl REJECTS a self-signed (un-notarized) bundle. This is
# not a failure of our signing -- only Developer ID + notarization
# passes spctl. We log it for visibility but do not fail on it.
echo "::group::spctl assessment (expected to be rejected)"
spctl -a -t exec -vv "$APP" || echo "(expected) spctl rejected the self-signed bundle"
echo "::endgroup::"

- name: Test embedded interpreter loads a foreign C extension
working-directory: repo/build/osx
env:
FOREIGN_PKG: ${{ inputs.foreign_test_package }}
run: |
set -e
APP="$PWD/FontForge.app"
FF="$APP/Contents/Resources/opt/local/bin/fontforge"
FFPY="$APP/Contents/MacOS/FFPython"
SITE="$RUNNER_TEMP/foreign-site"

# Install the foreign package AFTER the bundle was signed, so its .so
# keeps its own (non-our-identity) signature. Importing it through the
# hardened-runtime `fontforge` binary therefore exercises
# disable-library-validation: without that entitlement, Library
# Validation would reject the foreign-signed module.
"$FFPY" -m pip install --target "$SITE" --no-input "$FOREIGN_PKG"

cat > "$RUNNER_TEMP/import_test.py" <<EOF
import importlib, os, sys
print("python:", sys.version.split()[0])
import fontforge
print("fontforge:", fontforge.version())
# Import the package's compiled module to force a foreign dlopen.
mod = importlib.import_module("$FOREIGN_PKG")
print("imported foreign package:", mod.__name__, getattr(mod, "__file__", "?"))
# Confirm at least one compiled .so came from the foreign site dir.
so = [f for r,_,fs in os.walk("$SITE") for f in fs if f.endswith(".so")]
print("foreign .so files:", so or "(none -- pick a package with a C extension)")
EOF

echo "Running import test through the hardened-runtime fontforge binary..."
PYTHONPATH="$SITE" "$FF" -lang=py -script "$RUNNER_TEMP/import_test.py"
echo "OK: embedded interpreter loaded the foreign C extension under the hardened runtime."

- name: Rehearsal artifact (self-signed -- DO NOT DISTRIBUTE)
uses: actions/upload-artifact@v7
with:
name: macOS_appbundle_REHEARSAL_self-signed_DO_NOT_DISTRIBUTE
path: repo/build/osx/FontForge-*.dmg
Loading
Loading