googlefonts / googlefonts/fontc

fontc silently saturates data types if source input is too large

Open
#755 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
193
Forks
21
Avg merge
1d 20h
Merged PRs (30d)
60

Description

When a glyph has e.g. a width that is too large to fit into the `hmtx` table's `uint16 advanceWidth`, fonttools will let the `struct` module throw an exception. fontc instead silently saturates the data type.

* Example generator: https://gist.github.com/madig/f07d821171338062b3d132f4ccfbeb6c#file-generate-py
* TTX output of fontc-compiled font: https://gist.github.com/madig/f07d821171338062b3d132f4ccfbeb6c#file-a-xml

Note the -32769 in `a`'s points and the OS/2.xAvgCharWidth of 32767 instead of the larger average of `a` and `.notdef`. Also note that the rectangle is 65535 font units across in the sources, but the glyf coordinates after the first point are relative to the last one and an int16 at most, so there is something going on there as well.

I have so far identified these fields as in danger of saturation or wrapping:

* `(h|v)mtx` table `advanceWidth` fields are uint16 (https://learn.microsoft.com/en-us/typography/opentype/spec/hmtx, https://learn.microsoft.com/en-us/typography/opentype/spec/vmtx#vertical-metrics-table-format) but `OS/2` table `xAvgCharWidth` field is int16, limiting the maximum advance width
* Variable fonts may use a width of 65535 as a hack according to Cosimo:
> and the width you can set it to 0xFFFF if you like for a static font, it's just when that font is used as a master to build a VF, varLib interprets that value as a signal to skip that glyph when computing glyph metrics variations. it's a hack that works and nobody wants to build real fonts with such a huge advance widths/heights (for now)
* `glyf` table `xCoordinates` and `yCoordinates` are int16, but all points after the first one are relative to the last one. All non-first points must be within int16 distance of the last one.

I'm not sure if fontTools is misinterpreting saturated but valid data, but maybe fontc should stop compilation and let the user know that something is off.

Contributor guide

No contributing guide indexed for this repository

Research direction

Check the fontc table-serialization paths for hmtx/vmtx, OS/2, and glyf, using the linked generator and TTX output as reproduction artifacts. Compare source values with emitted fields and define completion as handling out-of-range advance widths and coordinate deltas without silent saturation or wrapping, with compilation behavior matching the chosen validation policy.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.