Skip to content

Don't pre-allocate the Type1 /Subrs array from the declared count - #32062

Merged
tacaswell merged 4 commits into
matplotlib:mainfrom
vsaraikin:fix/type1font-subrs-preallocation
Jul 31, 2026
Merged

Don't pre-allocate the Type1 /Subrs array from the declared count#32062
tacaswell merged 4 commits into
matplotlib:mainfrom
vsaraikin:fix/type1font-subrs-preallocation

Conversation

@vsaraikin

Copy link
Copy Markdown
Contributor

Fixes #31962.

When parsing a Type1 font, _parse_subrs read the declared /Subrs count and immediately did array = [None] * count, before reading the body. The count comes straight from the font file, so a malformed font can declare a huge count in a handful of bytes and force a large allocation before anything is validated. _parse_charstrings already avoids this by accumulating into a dict, so this just brings _parse_subrs in line.

The change accumulates the parsed entries into a dict and only allocates the count-sized result list once the body has actually been read.

The regression test builds a tiny font that declares /Subrs 5000000 array with an empty body. On master that allocates ~40 MB ([None] * 5000000) before the parse fails; with the change the parse still fails the same way but peak allocation stays small. The test uses tracemalloc and asserts the peak stays under 5 MB.

_parse_subrs allocated [None] * count from the count declared in the font
before reading the body, so a malformed font declaring a huge count could
force a large allocation before being rejected. Accumulate entries into a
dict and build the list after the body parses, matching _parse_charstrings.
@github-actions

Copy link
Copy Markdown

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks. We also ask that you please finish addressing any review comments on this PR and wait for it to be merged (or closed) before opening a new one, as it can be a valuable learning experience to go through the review process.

You can also join us on discourse chat for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide.
Please let us know if (and how) you use AI, it will help us give you better feedback on your PR.

We strive to be a welcoming and open project. Please follow our Code of Conduct.

Comment thread lib/matplotlib/_type1font.py Outdated
Comment thread lib/matplotlib/tests/test_type1font.py Outdated
Comment thread lib/matplotlib/_type1font.py Outdated
"Malformed Type1 font file: Incomplete /Subrs"
) from None

array = [None] * count

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we are being more careful, we should also check that the length of entries == count and the maximum key is count -1.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

@tacaswell
tacaswell merged commit f36e063 into matplotlib:main Jul 31, 2026
41 checks passed
@tacaswell

Copy link
Copy Markdown
Member

Thank you @vsaraikin and congratulations on your first merged Matplotlib PR 🎉 I hope we hear from you agian.

@QuLogic QuLogic added this to the v3.11.2 milestone Jul 31, 2026
@QuLogic

QuLogic commented Jul 31, 2026

Copy link
Copy Markdown
Member

@meeseeksdev backport to v3.11.x

timhoffm pushed a commit that referenced this pull request Jul 31, 2026
timhoffm added a commit that referenced this pull request Jul 31, 2026
…062-on-v3.11.x

Backport PR #32062 on branch v3.11.x (Don't pre-allocate the Type1 /Subrs array from the declared count)
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.

[Bug]: Type1Font allocates /Subrs array from declared count before validating the body

5 participants