Skip to content

v1.10.1

Choose a tag to compare

@github-actions github-actions released this 25 Oct 00:17
· 20 commits to main since this release

Added

  • CheckPdfUA(PdfUAPart.Part2) and the part-2 save check the structure rules for Ruby (ISO 14289-2 8.2.5.23), Warichu (8.2.5.24), Caption position (8.2.5.27), MathML placement and associated files (8.2.5.29), and the parent/child structure type table (Table 5), which keeps Em and Strong inline. The MathML namespace is accepted. Part 1 is unchanged. See docs/pdfua.md for what stays unchecked.

Fixed

  • Flate decoding could fail or lose its place in some valid streams. The decoder's fast loop reads up to three symbols after one refill of its bit buffer, and assumed that 56 bits were enough. A literal followed by a length/distance pair with long Huffman codes can need up to 63, so the bit count went negative and the stream desynchronised. Depending on the data this raised a spurious "invalid code" or "distance" error, or produced wrong output that only a trailing Adler-32 would reveal. The decoder now refills before such a pair. Streams are checked against the platform's inflate at every split point and under random chunking.
  • PNG images that are decoded (interlaced images and images with an alpha channel, and embedded ICC profiles) now fail when the zlib checksum at the end of the data does not match, instead of accepting damaged pixels. Flate streams in PDF files stay lenient: the data is kept and a mismatch is recorded as a diagnostic, as before.

Changed

  • Less memory when interpreting and extracting large documents; output is unchanged (display-list text, snapshots and extraction JSON are byte-identical). A PdfDisplayList stores glyph runs more compactly: glyphs keep only their own fields (vertical-writing fields and outlines live in side tables, and repeated library-owned outlines are shared), and the font, size, spacing and mode of a run are stored once and shared between runs. A large Flate stream with no known size (typically a content stream) is measured by a first inflate pass and then decoded into one array of exactly that size, instead of growing segments that were joined and discarded, so it allocates about once its size. Compressed input under 128 KiB is unaffected. On two large corpus files, whole-document extraction plus interpretation of every page into a display list allocated 12 % and 22 % less, and each phase's peak working set fell by 14 to 19 %.