[
https://issues.apache.org/jira/browse/PDFBOX-6297?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18144794#comment-18144794
]
Andreas Lehmkühler commented on PDFBOX-6297:
--------------------------------------------
[~netwind] Thanks for the report. I've fixed the issue but it wasn't as easy as
proposed.
In contrast to format 8 format 12/13 cmap tables have a maximum of 0x0010FFFF
nbgroups at least theorectically. However, there was another more important
issue: the missing check for the sorting of the nbgroups. According to the spec
the nbgroups have to be sorted in ascending order without any overlapping. I've
added the addtional check as well so that everything should be save now.
> cmap format 12/13: nbGroups is unbounded, a 1.2 MB font takes 41 minutes to
> parse
> ---------------------------------------------------------------------------------
>
> Key: PDFBOX-6297
> URL: https://issues.apache.org/jira/browse/PDFBOX-6297
> Project: PDFBox
> Issue Type: Bug
> Components: FontBox
> Affects Versions: 2.0.37, 3.0.8 PDFBox, 4.0.0
> Environment: FontBox 3.0.8, JDK 21.0.11, Windows 11
> Reporter: netwind
> Assignee: Andreas Lehmkühler
> Priority: Major
> Fix For: 2.0.38, 3.0.9 PDFBox, 4.0.0
>
> Attachments: Cmap12Poc.java, poc-cmap13-100k.ttf, poc-cmap13-1k.ttf,
> run-output.txt, run-poc.bat
>
>
> FontBox 3.0.8, Java 21.0.11, Windows 11. The trunk code of CmapSubtable is
> the same except for the logging calls.
> processSubtype12 and processSubtype13 read nbGroups as a 32-bit value and
> never check it. processSubtype8 in the same file caps the same field at
> 65536, with the comment "nbGroups shouldn't be greater than 65536".
> For format 13 the inner loop runs once per character code of every group, so
> a group of (0, 0x10FFFF, 0) is 12 bytes that become 1,114,112 map puts, and
> the outer loop repeats that until the data ends. With a minimal but valid TTF
> (nine tables, maxp claims 2 glyphs, one format 13 subtable, 100,000 groups,
> 1.2 MB) TTFParser.parseEmbedded takes 41 minutes on one core. The parse
> succeeds, no warnings, memory stays around 100 MB - it is just slow. 1,000
> groups (12 KB) already take 25 seconds.
> Format 12 is affected as well, but its inner loop stops at the first glyph
> index at or above numGlyphs, so a group is capped at numGlyphs puts; 10,000
> groups (131 KB, numGlyphs=65535) take 16 seconds.
> Expected: a font this small parses in a second or two. Actual: one core
> pinned for minutes.
> Both sample fonts and the generator are attached. "run-poc.bat 13 100000"
> reproduces the 41 minute case. Suggested fix: give format 12 and 13 the same
> 65536 cap format 8 has, or compare nbGroups against the bytes left in the
> table.
> {code:java}
> // CmapSubtable.java, line 300 (13) and 243 (12) in 3.0.8
> long nbGroups = data.readUnsignedInt(); // no upper bound
> ...
> for (long j = 0; j <= endCode - firstCode; ++j) { // up to 0x110000 puts per
> group
> characterCodeToGlyphId.put((int) (firstCode + j), (int) glyphId);
> }
> {code}
> One more thing in the same function: processSubtype13 checks "glyphId >
> numGlyphs" and then indexes glyphIdToCharacterCode[glyphId], so glyphId ==
> numGlyphs passes the check and throws AIOOBE instead of the intended warning.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]