[ 
https://issues.apache.org/jira/browse/PDFBOX-6297?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

netwind updated PDFBOX-6297:
----------------------------
    Attachment: Cmap12Poc.java
                run-poc.bat
                poc-cmap13-1k.ttf
                poc-cmap13-100k.ttf
                run-output.txt

> 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: 3.0.9 PDFBox
>         Environment: FontBox 3.0.8, JDK 21.0.11, Windows 11
>            Reporter: netwind
>            Priority: Major
>         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]

Reply via email to