Skip to content

Add code for validating OpenType GLYF table entries#12375

Merged
mitchellh merged 3 commits intoghostty-org:mainfrom
qwerasd205:ot-glyf-table
Apr 23, 2026
Merged

Add code for validating OpenType GLYF table entries#12375
mitchellh merged 3 commits intoghostty-org:mainfrom
qwerasd205:ot-glyf-table

Conversation

@qwerasd205
Copy link
Copy Markdown
Member

This code was motivated by the need for the glyph protocol handler (#12352) to be able to validate the provided glyf payload, without having to link freetype or anything (because libghostty-vt needs to be static). As such it's written specifically to meet those needs, but in such a way that it can be expanded if we find a need for more in-depth inspection of glyfs in the future.

We want to have this for the glyph protocol so that we can validate
passed glyf data in libghostty without having to link freetype or
anything like that.
Also fixes a logic bug where we weren't counting the length of x
coordinates and y coordinates correctly when we had repeated flags.
@qwerasd205 qwerasd205 requested a review from a team as a code owner April 22, 2026 17:50
Copy link
Copy Markdown
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the spec

If a glyph has zero contours, no additional glyph data beyond the header is required. A glyph with zero contours may have additional data, however; in particular, it may have instructions that operate on phantom points.

This test should pass:

test "glyf: zero-contour glyph can be header-only" {
    const testing = std.testing;

    const header: Glyf.Entry.Header = .{
        .numberOfContours = 0,
        .xMin = 0,
        .yMin = 0,
        .xMax = 0,
        .yMax = 0,
    };
    const glyph = try Glyf.Entry.init(std.mem.asBytes(&header));
    try testing.expectEqual(@sizeOf(Glyf.Entry.Header), try glyph.size());
}

@qwerasd205
Copy link
Copy Markdown
Member Author

Haha yeah I actually realized I had written that bug while I was going to sleep last night and going back over the spec in my head- adding a test (and if need be, a fix) for it was on my todo list for today.

@mitchellh
Copy link
Copy Markdown
Contributor

I realize for the purpose of the glyph protocol its a silly glyph cause its... empty... but it is valid. 🤷

@qwerasd205
Copy link
Copy Markdown
Member Author

qwerasd205 commented Apr 23, 2026

But actually, no that test is incorrect-- the additional data after the header is a few bytes still since it has to encode the instructions length. At least 2 extra bytes for the 16-bit instructionLength field, and then however many bytes for the instructions array.

The spec is worded in a confusing way that seems to imply a bare header should be allowed but I have no clue how that would function in an actual font file, since there's nothing in the header that encodes whether or not it potentially contains instructions... oh, oh no actually the length of any entry is determined by the difference to the subsequence loca offset, so I guess it does need to allow truncation after the header if the contour count is 0.

@mitchellh
Copy link
Copy Markdown
Contributor

It is confusing, and semantically for our use case it probably doesn't matter. I read this:

however; in particular, it may have instructions that operate on phantom points.

As meaning the instructions part was optional.

@qwerasd205
Copy link
Copy Markdown
Member Author

Yep, see my edits on my last reply. I'll make a fix for it in an hour or so.

@mitchellh mitchellh merged commit c1b685b into ghostty-org:main Apr 23, 2026
87 of 89 checks passed
@github-actions github-actions Bot added this to the 1.4.0 milestone Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants