Repository navigation
Conversation
`ImageRef.pil_image` is annotated `PILImage.Image | None` and
`FloatingItem.get_image` documents that it returns None when no image is
available, but both forwarded `PILImage.open` without a guard:
>>> ref = ImageRef(dpi=72, mimetype="image/svg+xml", size=Size(width=120, height=80),
... uri=AnyUrl("data:image/svg+xml;base64,..."))
>>> ref.pil_image
PIL.UnidentifiedImageError: cannot identify image file
An inline `data:image/svg+xml` image is the case that surfaced this: Pillow
has no SVG decoder, so a Markdown or HTML backend that keeps such an image as a
reference produces a ref that raises. `FloatingItem.get_image` then raised
instead of returning None, and its callers that skip a picture without an image
broke - the picture enrichment models through `BaseItemAndImageEnrichmentModel
.prepare_element`, and every consumer walking the pictures of such a document.
A `data:` payload that simply is not image data, and a local image file that
is no longer readable, reach the same path today.
Catch UnidentifiedImageError and return None, which is what the annotations and
the docstring already promise. Refusal to read a source at all stays an error:
a blocked `file:` URI and a payload past `max_image_decoded_size` keep
raising ValueError, as their existing tests require.
Signed-off-by: simpleqt <2015900818@qq.com>
Contributor
|
✅ DCO Check Passed Thanks @simpleqt, all your commits are properly signed off. 🎉 |
Contributor
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
Contributor
Merge Protections🔴 1 of 2 protections blocking · waiting on 👀 reviews
🔴 Require two reviewer for test updatesWaiting for
This rule is failing.When test data is updated, we require two reviewers
Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix: return None from
pil_imagewhen the reference cannot be decodedImageRef.pil_imageis annotatedPILImage.Image | None, andFloatingItem.get_imagedocuments that it returnsNonewhen no image isavailable — but both forwarded
PILImage.openwithout a guard:Three ways to reach it today:
data:image/svg+xmlreference — Pillow has no SVG decoder, and aMarkdown or HTML backend that keeps such an image as a reference produces
exactly this ref
data:payload that is not image data at allThe consequence is not a missing image, which callers already skip, but an
exception from a method that promises
None:BaseItemAndImageEnrichmentModel.prepare_elementcallselement.get_image(...)to feed the picture-description and classification models, and anything else
walking the pictures of a document inherits the crash.
The fix catches
UnidentifiedImageErrorand returnsNone, which is what theannotations and the docstring already promise.
Refusal to read a source at all stays an error. A blocked
file:URI and apayload past
max_image_decoded_sizekeep raisingValueError; those arepinned by
test_image_ref_blocks_file_schemeandtest_image_ref_blocks_oversized_base64, which still pass. Only the decoderfailing to identify the data is swallowed.
Testing
Two tests in
tests/test_docling_doc.py:test_get_image_of_an_undecodable_ref_returns_none— a document with an inlineSVG reference; asserts the payload is still referenced (
image is not None),that
pil_imageis nowNone, and thatPictureItem.get_image(doc)returnsNoneinstead of raisingtest_pil_image_of_a_corrupt_data_uri_returns_none— adata:image/pngpayload that is not image data
With the new tests but the source at the base revision:
22 failed, 106 passed; with the fix:20 failed, 108 passed. The delta isexactly these two tests, and the 20 remaining failures are pre-existing (they
fail identically on the unmodified base commit — a Windows path artifact in the
test_load_local_images_*family andtest_save_to_disk).ruffat the pre-commit revision (0.16.10) passescheckandformat --checkon both changed files.
Unrelated to this change: running the suite rewrites
tests/data/doc/constructed_doc.dtin the working tree (a line-ending artifacton Windows). It is not part of this commit.
Why this is here rather than in docling
This surfaced while fixing docling#4742
in
docling, where an inlinedata:image/svg+xmlimage was silently droppedbecause
create_image_refhanded the payload toPIL.Image.openand returnedNonewhen it failed. Keeping the payload as anImageRefis the natural fixthere, but it only works once
get_image()returnsNonefor a ref that cannotbe decoded — otherwise it converts silent data loss into a crash in the picture
enrichment path. I withdrew that PR
(docling#4925) rather
than ship the regression; this is the part that belongs here, and it is a defect
on its own for corrupt data URIs and unreadable local files.
AI assistance: this change was produced with AI assistance (an autonomous coding
agent); the analysis, the reproduction, the before/after test runs and the lint
runs were executed locally, and a human reviewed the result before submission.