Skip to content

FIX: Added ft2font null checks added#31557

Merged
QuLogic merged 1 commit intomatplotlib:mainfrom
beelauuu:beelauuu/ft2font-null-fixes
May 7, 2026
Merged

FIX: Added ft2font null checks added#31557
QuLogic merged 1 commit intomatplotlib:mainfrom
beelauuu:beelauuu/ft2font-null-fixes

Conversation

@beelauuu
Copy link
Copy Markdown
Contributor

@beelauuu beelauuu commented Apr 23, 2026

PR summary

Fix two potential null pointer crashes in src/ft2font.h and src/ft2font_wrapper.cpp.

1. ft_error_string returning NULL (ft2font.h:44)

Fixed by changing the default case to return "unknown error" instead of NULL, so the function always returns a valid string.

2. NULL family_name streamed in ft_glyph_warn (ft2font_wrapper.cpp:408)

Fixed by guarding each stream insertion with (*it ? *it : "unknown").

AI Disclosure

I used Claude Code to help understand the codebase. The fixes were applied by me.

PR checklist

  • [N/A] "closes #0000" — no linked issue
  • new and changed code is tested
  • [N/A] Plotting related features are demonstrated in an example
  • [N/A] New Features and API Changes are noted with a directive and release note — these are defensive bug fixes with no API changes
  • [N/A] Documentation complies with general and docstring guidelines — no docs changed

@beelauuu beelauuu changed the title ft2font null checks added FIX: Added ft2font null checks added Apr 23, 2026
@beelauuu
Copy link
Copy Markdown
Contributor Author

Do I need to write a test for this? The changes feel pretty trivial.

@story645
Copy link
Copy Markdown
Member

Do I need to write a test for this? The changes feel pretty trivial.

Please do, it's worth checking that this code can be triggered.

@beelauuu
Copy link
Copy Markdown
Contributor Author

Do I need to write a test for this? The changes feel pretty trivial.

Please do, it's worth checking that this code can be triggered.

I just took a look at a test for this. The test_fallback_missing_glyph_warn_family_names test covers the same ft_glyph_warn code path for the common case (real family names) and would catch any regression that broke the formatting logic entirely. Directly testing the null branch would require either exposing FT_Select_Size to Python or adding a dedicated C-level test hook, both of which feel excessive for the 1 line change.

@beelauuu
Copy link
Copy Markdown
Contributor Author

@story645 Any thoughts? If the testing requirement is stringent and you can think of any alternatives/somebody else wants to take it over, I can also close it out.

@story645
Copy link
Copy Markdown
Member

story645 commented Apr 28, 2026

or adding a dedicated C-level test hook, both of which feel excessive for the 1 line change.

does that mean the error message "unknown error" never gets propagated up?

And I think here the testing requirement isn't that stringent - looks like the coverage decreases are unrelated.

@beelauuu
Copy link
Copy Markdown
Contributor Author

beelauuu commented Apr 28, 2026

does that mean the error message "unknown error" never gets propagated up?

After digging a little bit, the only font format where FreeType would reutnr a null family_name is BDF (bitmap fonts without a FAMILY_NAME property), but matplotlib's set_size calls FT_Set_Char_Size which fails for bitmap fonts, so you can't size the face and trigger a glyph warning through the normal API.

The null check is really more just preventative but seems like it may honestly just never be triggered. From a correctness standpoint, it won't hurt.

Copy link
Copy Markdown
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

I don't really see any way that FT_ERROR_END_LIST would be triggered, but might as well be safe.

@QuLogic QuLogic added this to the v3.11.0 milestone Apr 30, 2026
@ksunden
Copy link
Copy Markdown
Member

ksunden commented Apr 30, 2026

I am a bit unconvinced by the need to remove NULL in at least the error list case.

The docs for the correlating Freetype function specifically say it can return NULL:

https://freetype.org/freetype2/docs/reference/ft2-error_enumerations.html

The example code for how to interact with these also includes a NULL (though interestingly only in one of the two examples, and not in the version that is most similar to what we have with a switch statement (which does not have a default case at all)

Given that NULL is an expected, documented return value here, I do not see the need to preemptively remove a NULL.

@beelauuu
Copy link
Copy Markdown
Contributor Author

I am a bit unconvinced by the need to remove NULL in at least the error list case.

The docs for the correlating Freetype function specifically say it can return NULL:

https://freetype.org/freetype2/docs/reference/ft2-error_enumerations.html

The example code for how to interact with these also includes a NULL (though interestingly only in one of the two examples, and not in the version that is most similar to what we have with a switch statement (which does not have a default case at all)

Given that NULL is an expected, documented return value here, I do not see the need to preemptively remove a NULL.

Sorry if I'm not following but given the fact that we expect a NULL shouldn't we guard against that in order to avoid de referencing a NULL pointer?

@ksunden
Copy link
Copy Markdown
Member

ksunden commented May 1, 2026

I am referring to the change to FT_ERROR_END_LIST in my previous comment, which removes a return NULL in a usecase where NULL is an expected, documented return.

I am not referring to the check when dereferencing.

@beelauuu
Copy link
Copy Markdown
Contributor Author

beelauuu commented May 1, 2026

I am referring to the change to FT_ERROR_END_LIST in my previous comment, which removes a return NULL in a usecase where NULL is an expected, documented return.

I am not referring to the check when dereferencing.

Ah ok, I see what you're getting at. Leaning towards your argument; can revert the change if others agree but honestly this feels like a relatively uneventful, trivial change.

@QuLogic
Copy link
Copy Markdown
Member

QuLogic commented May 1, 2026

This is a weird one, because we aren't actually using FT_Error_String but a wrapper, and I'm not entirely sure why. It's possible that @anntzer did that because of this note in the docs:

FreeType has to be compiled with FT_CONFIG_OPTION_ERROR_STRINGS or FT_DEBUG_LEVEL_ERROR to get meaningful descriptions. ‘error_string’ will be NULL otherwise.

However, since we aren't using FT_Error_String, but our own internal ft_error_string, the docs about NULL return do not matter here.

@anntzer
Copy link
Copy Markdown
Contributor

anntzer commented May 3, 2026

FT_Error_String is relatively new (it's there since FT 2.10.0, which we still don't actually require). I guess we could bump the required FT version, though.
Returning "unknown error" in that case (which is only ever used by THROW_FT_ERROR) also makes sense to me.

@QuLogic
Copy link
Copy Markdown
Member

QuLogic commented May 7, 2026

FT_Error_String is relatively new (it's there since FT 2.10.0, which we still don't actually require). I guess we could bump the required FT version, though.

Yea, probably we should tighten up what version is required there, but that's a separate question.

@QuLogic QuLogic merged commit 0f64fb9 into matplotlib:main May 7, 2026
40 of 42 checks passed
QuLogic added a commit that referenced this pull request May 7, 2026
…557-on-v3.11.x

Backport PR #31557 on branch v3.11.x (FIX: Added ft2font null checks added)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants