py-pdf / pypdf

A pure-python PDF library capable of splitting, merging, cropping, and transforming the pages of PDF files
https://pypdf.readthedocs.io/en/latest/
Other
8.43k stars 1.42k forks source link

#5 Using PdfReader causes a crash #2866

Closed Avgor46 closed 2 months ago

Avgor46 commented 2 months ago

Hi!

Another crash similar to previous ones. Pdf and stderr could be found below.

Environment

Which environment were you using when you encountered the problem?

$ python -m platform
Linux-5.15.0-56-generic-x86_64-with-glibc2.31

$ python -c "import pypdf;print(pypdf._debug_versions)"
pypdf==5.0.0, crypt_provider=('cryptography', '3.1'), PIL=none

commit 6cfa0c4fe8d8d9a144e32f120066e9de17005d04

Code + PDF

This is a minimal, complete example that shows the issue:

#! /usr/bin/env python3

import pypdf
from pypdf.errors import EmptyFileError, PdfReadError, PdfStreamError
import sys

def TestOneInput(fname):
  try:
    pdf_reader = pypdf.PdfReader(fname)
    for page_number, page in enumerate(pdf_reader.pages):
        page.extract_text()
  except (EmptyFileError, PdfReadError, PdfStreamError):
      pass

if __name__ == "__main__":
    if len(sys.argv) < 2:
        exit(1)
    TestOneInput(sys.argv[1])

PoC

crash-e108c4f677040b61e12fa9f1cfde025d704c9b0d.pdf

Traceback

This is the complete stderr I see:

PdfReadError("Invalid Elementary Object starting with b'M' @276: b'ASGAA+Arial,Unicode MS\\n/DescendantFonts [ 56 0 R ]\\n/Encoding /Identity-H\\n/Subtyp'")
Traceback (most recent call last):
  File "/fuzz/./poc.py", line 18, in <module>
    TestOneInput(sys.argv[1])
  File "/fuzz/./poc.py", line 11, in TestOneInput
    page.extract_text()
  File "/usr/local/lib/python3.9/dist-packages/pypdf/_page.py", line 2266, in extract_text
    return self._extract_text(
  File "/usr/local/lib/python3.9/dist-packages/pypdf/_page.py", line 1761, in _extract_text
    cmaps[f] = build_char_map(f, space_width, obj)
  File "/usr/local/lib/python3.9/dist-packages/pypdf/_cmap.py", line 32, in build_char_map
    font_subtype, font_halfspace, font_encoding, font_map = build_char_map_from_dict(
  File "/usr/local/lib/python3.9/dist-packages/pypdf/_cmap.py", line 53, in build_char_map_from_dict
    font_type: str = cast(str, ft["/Subtype"])
  File "/usr/local/lib/python3.9/dist-packages/pypdf/generic/_data_structures.py", line 441, in __getitem__
    return dict.__getitem__(self, key).get_object()
KeyError: '/Subtype'
pubpub-zz commented 2 months ago

your file does not respect the PDF spec as a name object contains a space whereas it should be encoded as #20 currently this stops the parsing of the object not creating the missing fields. PR in progress to not stop the processing.