From af6a8f7b83c9c33b5fedfa0987d54f817f3b3cba Mon Sep 17 00:00:00 2001 From: Steve Canny Date: Wed, 31 Jul 2024 18:06:19 -0700 Subject: [PATCH] fix: #929 raises on JPEG with image/jpg MIME-type At least one client, perhaps Adobe PDF Converter, produces a PPTX with JPEG images mapped to the non-existent `image/jpg` MIME-type rather than the correct `image/jpeg`. Accept `image/jpg` as an alias for `image/jpeg`, which is consistent with the behavior of PowerPoint which loads these files without complaint. --- HISTORY.rst | 4 +++- features/prs-open-save.feature | 4 ++++ features/steps/presentation.py | 21 ++++++++++++++++++ .../steps/test_files/test-image-jpg-mime.pptx | Bin 0 -> 33400 bytes src/pptx/__init__.py | 4 +++- 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 features/steps/test_files/test-image-jpg-mime.pptx diff --git a/HISTORY.rst b/HISTORY.rst index 88b6580b..73c3bace 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,13 +3,15 @@ Release History --------------- -0.6.24-dev3 +0.6.24-dev4 +++++++++++++++++++ +- fix: #929 raises on JPEG with image/jpg MIME-type - fix: #943 remove mention of a Px Length subtype - fix: #972 next-slide-id fails in rare cases - fix: #990 do not require strict timestamps for Zip + 0.6.23 (2023-11-02) +++++++++++++++++++ diff --git a/features/prs-open-save.feature b/features/prs-open-save.feature index 4176adfd..d60b2c24 100644 --- a/features/prs-open-save.feature +++ b/features/prs-open-save.feature @@ -33,3 +33,7 @@ Feature: Round-trip a presentation When I save and reload the presentation Then the external relationships are still there And the package has the expected number of .rels parts + + Scenario: Load presentation with invalid image/jpg MIME-type + Given a presentation with an image/jpg MIME-type + Then I can access the JPEG image diff --git a/features/steps/presentation.py b/features/steps/presentation.py index 0c1c6ba2..11a25954 100644 --- a/features/steps/presentation.py +++ b/features/steps/presentation.py @@ -5,6 +5,7 @@ import io import os import zipfile +from typing import TYPE_CHECKING, cast from behave import given, then, when from behave.runner import Context @@ -14,6 +15,10 @@ from pptx.opc.constants import RELATIONSHIP_TYPE as RT from pptx.util import Inches +if TYPE_CHECKING: + from pptx import presentation + from pptx.shapes.picture import Picture + # given =================================================== @@ -38,6 +43,11 @@ def given_a_presentation_having_no_notes_master(context: Context): context.prs = Presentation(test_pptx("prs-properties")) +@given("a presentation with an image/jpg MIME-type") +def given_prs_with_image_jpg_MIME_type(context): + context.prs = Presentation(test_pptx("test-image-jpg-mime")) + + @given("a presentation with external relationships") def given_prs_with_ext_rels(context: Context): context.prs = Presentation(test_pptx("ext-rels")) @@ -189,6 +199,17 @@ def then_the_package_has_the_expected_number_of_rels_parts(context: Context): assert member_count == 18, "expected 18, got %d" % member_count +@then("I can access the JPEG image") +def then_I_can_access_the_JPEG_image(context): + prs = cast("presentation.Presentation", context.prs) + slide = prs.slides[0] + picture = cast("Picture", slide.shapes[0]) + try: + picture.image + except AttributeError: + raise AssertionError("JPEG image not recognized") + + @then("the slide height matches the new value") def then_slide_height_matches_new_value(context: Context): presentation = context.presentation diff --git a/features/steps/test_files/test-image-jpg-mime.pptx b/features/steps/test_files/test-image-jpg-mime.pptx new file mode 100644 index 0000000000000000000000000000000000000000..857bd7ca29a7f32f1f9cd751b00a7b824fb4bd36 GIT binary patch literal 33400 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