From e818efc9e8d6b5276afb61e9347abff489bb6048 Mon Sep 17 00:00:00 2001 From: hetaoBackend Date: Thu, 6 Aug 2026 10:34:43 +0800 Subject: [PATCH] fix: preserve missing-upload delete contract --- backend/packages/harness/deerflow/uploads/manager.py | 7 ++++++- backend/tests/test_uploads_manager.py | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/packages/harness/deerflow/uploads/manager.py b/backend/packages/harness/deerflow/uploads/manager.py index 4f3334c62..3b4046d18 100644 --- a/backend/packages/harness/deerflow/uploads/manager.py +++ b/backend/packages/harness/deerflow/uploads/manager.py @@ -387,7 +387,12 @@ def delete_file_safe(base_dir: Path, filename: str) -> dict: safe_name = normalize_filename(filename) if safe_name != filename: raise PathTraversalError("Path traversal detected") - base_dir = _validate_upload_directory(Path(base_dir)) + try: + base_dir = _validate_upload_directory(Path(base_dir)) + except UnsafeUploadPathError as exc: + if isinstance(exc.__cause__, FileNotFoundError): + raise FileNotFoundError(f"File not found: {filename}") from exc + raise file_path = base_dir / safe_name try: file_stat = os.lstat(file_path) diff --git a/backend/tests/test_uploads_manager.py b/backend/tests/test_uploads_manager.py index 04af37de2..6f2612233 100644 --- a/backend/tests/test_uploads_manager.py +++ b/backend/tests/test_uploads_manager.py @@ -362,6 +362,10 @@ class TestDeleteFileSafe: with pytest.raises(FileNotFoundError): delete_file_safe(tmp_path, "nope.txt") + def test_delete_from_nonexistent_directory_raises_file_not_found(self, tmp_path): + with pytest.raises(FileNotFoundError, match="ghost.txt"): + delete_file_safe(tmp_path / "missing-uploads", "ghost.txt") + def test_delete_traversal_raises(self, tmp_path): with pytest.raises(PathTraversalError, match="traversal"): delete_file_safe(tmp_path, "../outside.txt")