From 5370571608d77302169d33a37122201fb8876409 Mon Sep 17 00:00:00 2001 From: Anas Khan <83116240+anxkhn@users.noreply.github.com> Date: Sun, 5 Jul 2026 13:14:33 +0530 Subject: [PATCH] types: make Image path extension check case-insensitive The guard in Image.serialize_model compared the file extension without normalizing case, so a non-existent path with an uppercase extension (e.g. photo.PNG from a camera or a case-insensitive filesystem) skipped the "File ... does not exist" branch and fell through to the base64 path. Filenames that happen to be valid base64 (PHOTO.PNG, DCIM0001.WEBP) were then silently accepted and sent as garbage image data instead of raising, defeating the extension guard for every uppercase-extension path. Lowercase the extracted extension before the membership test so .PNG/.JPG/.JPEG/.WEBP behave the same as their lowercase counterparts. Non-image strings still correctly fall through to the base64 check. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com> --- ollama/_types.py | 2 +- tests/test_type_serialization.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ollama/_types.py b/ollama/_types.py index 96529d63..b9bb53cb 100644 --- a/ollama/_types.py +++ b/ollama/_types.py @@ -175,7 +175,7 @@ def serialize_model(self): pass # String might be a file path, but might not exist - if self.value.split('.')[-1] in ('png', 'jpg', 'jpeg', 'webp'): + if self.value.split('.')[-1].lower() in ('png', 'jpg', 'jpeg', 'webp'): raise ValueError(f'File {self.value} does not exist') try: diff --git a/tests/test_type_serialization.py b/tests/test_type_serialization.py index f458cd23..02a69e95 100644 --- a/tests/test_type_serialization.py +++ b/tests/test_type_serialization.py @@ -55,6 +55,19 @@ def test_image_serialization_string_path(): img.model_dump() +@pytest.mark.parametrize('extension', ['PNG', 'JPG', 'JPEG', 'WEBP']) +def test_image_serialization_string_path_uppercase_extension(extension): + # A non-existent path with an uppercase image extension must be rejected the + # same way its lowercase counterpart is, rather than being treated as base64. + with pytest.raises(ValueError, match='does not exist'): + Image(value=f'some_path/that/does/not/exist.{extension}').model_dump() + + # A bare filename with an uppercase extension can be valid base64, so without a + # case-insensitive check it is silently accepted instead of raising. + with pytest.raises(ValueError, match='does not exist'): + Image(value=f'PHOTO.{extension}').model_dump() + + def test_create_request_serialization(): request = CreateRequest(model='test-model', from_='base-model', quantize='q4_0', files={'file1': 'content1'}, adapters={'adapter1': 'content1'}, template='test template', license='MIT', system='test system', parameters={'param1': 'value1'})