diff --git a/src/ocrmypdf/_weave.py b/src/ocrmypdf/_weave.py index 5108ad22..a2951042 100644 --- a/src/ocrmypdf/_weave.py +++ b/src/ocrmypdf/_weave.py @@ -25,7 +25,7 @@ from .helpers import flatten_groups, page_number def _update_page_resources(*, page, font, font_key, procset): - "Update this page's fonts with a reference to the Glyphless font" + """Update this page's fonts with a reference to the Glyphless font""" if '/Resources' not in page: page['/Resources'] = pikepdf.Dictionary({}) @@ -160,7 +160,7 @@ def _weave_layers_graft( def _find_font(text, pdf_base): - "Copy a font from the filename text into pdf_base" + """Copy a font from the filename text into pdf_base""" font, font_key = None, None possible_font_names = ('/f-0-0', '/F1') @@ -245,12 +245,14 @@ def _fix_toc(pdf_base, pageref_remap, log): Inner helper function: change the objgen for any page from the old we invalidated to its new one. """ - if not isinstance(dest_node, pikepdf.Array): - return + try: pageref = dest_node[0] if pageref['/Type'] == '/Page' and pageref.objgen in pageref_remap: new_objgen = pageref_remap[pageref.objgen] dest_node[0] = pdf_base.get_object(new_objgen) + except (IndexError, TypeError) as e: + log.warning("This file may contain invalid table of contents entries") + log.debug(e) def visit_remap_dest(pdf_base, node, log): """ diff --git a/tests/test_weave.py b/tests/test_weave.py new file mode 100644 index 00000000..ae7d8465 --- /dev/null +++ b/tests/test_weave.py @@ -0,0 +1,40 @@ +# © 2019 James R. Barlow: github.com/jbarlow83 +# +# This file is part of OCRmyPDF. +# +# OCRmyPDF is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OCRmyPDF is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OCRmyPDF. If not, see . + +from unittest.mock import MagicMock +import logging + +import pytest + +import pikepdf +from ocrmypdf._weave import _fix_toc + +def test_invalid_toc(resources, tmpdir, caplog): + pdf = pikepdf.open(resources / 'toc.pdf') + + # Corrupt a TOC entry + pdf.Root.Outlines.Last.Dest = pikepdf.Array([None, 0.0, 0.1, 0.2]) + pdf.save(tmpdir / 'test.pdf') + + pdf = pikepdf.open(tmpdir / 'test.pdf') + remap = {} + remap[pdf.pages[0].objgen] = pdf.pages[0].objgen # Dummy remap + + # Confirm we complain about the TOC and don't throw an exception + log = logging.getLogger() + _fix_toc(pdf, remap, log) + assert 'invalid table of contents entries' in caplog.text