Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docling_core/types/doc/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -1099,8 +1099,10 @@ def pil_image(self) -> Optional[PILImage.Image]:
raise ValueError(f"Decoded image exceeds size limit of {settings.max_image_decoded_size} bytes.")

self._pil = PILImage.open(BytesIO(decoded_img))
# else: Handle http request or other protocols...
# NOTE: any further protocol support added (https etc.) must adhere to respective sanitization practices
elif isinstance(self.uri, Path):
if not settings.allow_image_local_path:
raise ValueError("Loading images from local paths is not enabled.")
self._pil = PILImage.open(self.uri)

return self._pil
Expand Down
1 change: 1 addition & 0 deletions docling_core/utils/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class CoreSettings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="DOCLINGCORE_")

allow_image_file_uri: bool = False
allow_image_local_path: bool = False
max_image_decoded_size: int = 20 * 1024 * 1024 # 20MB


Expand Down
61 changes: 61 additions & 0 deletions test/test_docling_doc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import re
import tempfile
import warnings
from collections import deque
from copy import deepcopy
Expand Down Expand Up @@ -898,6 +899,66 @@ def test_file_uri_blocked_by_default():
_ = image_ref.pil_image


def test_local_path_blocked_by_default():
"""Test that local Path objects are blocked by default."""
image_ref = ImageRef(
dpi=72,
mimetype="image/png",
size=Size(width=100, height=100),
uri=Path("/etc/something"),
)

with pytest.raises(ValueError, match="Loading images from local paths is not enabled"):
_ = image_ref.pil_image


def test_local_path_allowed_with_setting():
"""Test that local Path objects work when enabled via settings."""
orig_allow_image_local_path = settings.allow_image_local_path

with tempfile.NamedTemporaryFile(suffix=".png") as tmp_file:
test_img_path = Path(tmp_file.name)

try:
img = PILImage.new("RGB", (50, 50), color="blue")
img.save(test_img_path)

settings.allow_image_local_path = True

image_ref = ImageRef(
dpi=72,
mimetype="image/png",
size=Size(width=50, height=50),
uri=test_img_path,
)

pil_img = image_ref.pil_image
assert pil_img is not None
assert pil_img.size == (50, 50)
assert pil_img.mode == "RGB"
finally:
settings.allow_image_local_path = orig_allow_image_local_path


def test_local_path_traversal_blocked():
"""Test that path traversal attempts are blocked by default."""
paths_to_check = [
Path("/etc/something"),
Path("../../../etc/something"),
]

for path in paths_to_check:
image_ref = ImageRef(
dpi=72,
mimetype="image/png",
size=Size(width=100, height=100),
uri=path,
)

with pytest.raises(ValueError, match="Loading images from local paths is not enabled"):
_ = image_ref.pil_image


def test_max_decoded_size_custom():
"""Test that oversized images are rejected based on custom limit."""
orig_max_image_decoded_size = settings.max_image_decoded_size
Expand Down
Loading