Skip to content

Commit ce6146d

Browse files
Anri-LombardAnri Lombardpre-commit-ci[bot]
authored
fix: sanitize filename with path separators in FileSchema.decode (#5533)
* fix: sanitize filename with path separators in FileSchema.decode Fixes #5532 When users upload files with filenames containing path separators (e.g., "payslips/red/genuine/uuid.pdf"), the filename was passed directly to tempfile.NamedTemporaryFile() as a suffix, causing a FileNotFoundError because the temp file system tried to create nested directories that don't exist. This change uses os.path.basename() to extract only the filename from the path, preventing the error while preserving the file extension for proper handling. * ci: auto fixes from pre-commit.ci For more information, see https://pre-commit.ci --------- Co-authored-by: Anri Lombard <anri.m.lombard@sprinthive.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 31ccc0b commit ce6146d

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/_bentoml_sdk/validators.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ def decode(self, obj: bytes | t.BinaryIO | UploadFile | PurePath | str) -> t.Any
155155
raise ValueError(
156156
f"Invalid content type {media_type}, expected {self.content_type}"
157157
)
158+
suffix = os.path.basename(filename) if filename else None
158159
with tempfile.NamedTemporaryFile(
159-
suffix=filename, dir=request_temp_dir(), delete=False
160+
suffix=suffix, dir=request_temp_dir(), delete=False
160161
) as f:
161162
f.write(body)
162163
return Path(f.name)

tests/unit/_bentoml_sdk/__init__.py

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from __future__ import annotations
2+
3+
import io
4+
from pathlib import Path
5+
from unittest.mock import patch
6+
7+
from starlette.datastructures import UploadFile
8+
9+
from _bentoml_sdk.validators import FileSchema
10+
11+
12+
def test_file_schema_decode_with_path_separator_in_filename(tmp_path: Path):
13+
file_content = b"test content"
14+
upload_file = UploadFile(
15+
file=io.BytesIO(file_content),
16+
filename="subdir/nested/document.pdf",
17+
)
18+
19+
with patch(
20+
"bentoml._internal.context.request_temp_dir", return_value=str(tmp_path)
21+
):
22+
result = FileSchema().decode(upload_file)
23+
24+
assert isinstance(result, Path)
25+
assert result.exists()
26+
assert result.read_bytes() == file_content
27+
assert result.suffix == ".pdf"

0 commit comments

Comments
 (0)