From 12314fcaa8d9137b0d4f36c1e620c9092882ed25 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Mon, 21 Sep 2026 22:21:24 +0800 Subject: [PATCH] Fix: ignore invalid EXIF orientation when generating image archives (#14203) Images with an out-of-spec EXIF orientation value (e.g. 0) fail conversion with img2pdf.ExifOrientationError, which aborts archive generation and, during consumption with OCR disabled, fails the whole document. Pass rotation=img2pdf.Rotation.ifvalid so invalid orientation values are ignored while valid values (1, 3, 6, 8) are still applied. Co-authored-by: zhzy0077 --- src/paperless/parsers/tesseract.py | 6 ++++- .../parsers/test_convert_image_to_pdfa.py | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/paperless/parsers/tesseract.py b/src/paperless/parsers/tesseract.py index f3ebf9925..1091dffda 100644 --- a/src/paperless/parsers/tesseract.py +++ b/src/paperless/parsers/tesseract.py @@ -394,7 +394,11 @@ class RasterisedDocumentParser: plain_pdf_path = Path(self.tempdir) / "image_plain.pdf" try: - convert_kwargs: dict = {} + convert_kwargs: dict = { + # Ignore invalid EXIF orientation values (e.g. 0) instead of + # aborting the conversion; valid values are still applied + "rotation": img2pdf.Rotation.ifvalid, + } if self.settings.image_dpi is not None: convert_kwargs["layout_fun"] = img2pdf.get_fixed_dpi_layout_fun( (self.settings.image_dpi, self.settings.image_dpi), diff --git a/src/paperless/tests/parsers/test_convert_image_to_pdfa.py b/src/paperless/tests/parsers/test_convert_image_to_pdfa.py index 615900a25..46261ffcf 100644 --- a/src/paperless/tests/parsers/test_convert_image_to_pdfa.py +++ b/src/paperless/tests/parsers/test_convert_image_to_pdfa.py @@ -18,6 +18,7 @@ import img2pdf import magic import pikepdf import pytest +from PIL import Image from documents.parsers import ParseError @@ -139,3 +140,24 @@ class TestConvertImageToPdfa: tesseract_parser._convert_image_to_pdfa(simple_png_file) spy.assert_not_called() + + def test_invalid_exif_orientation_is_ignored( + self, + tesseract_parser: RasterisedDocumentParser, + tmp_path: Path, + ) -> None: + """ + GIVEN: a JPEG with an invalid EXIF orientation value (0) + WHEN: _convert_image_to_pdfa is called + THEN: the invalid value is ignored and a valid PDF is produced + """ + image_path = tmp_path / "invalid_orientation.jpg" + with Image.new("RGB", (120, 80), "white") as image: + exif = image.getexif() + exif[274] = 0 # EXIF tag 274: Orientation + image.save(image_path, exif=exif) + + result = tesseract_parser._convert_image_to_pdfa(image_path) + + assert result.exists() + assert magic.from_file(str(result), mime=True) == "application/pdf"