Skip to content

Commit ddf8d6e

Browse files
fix(outline-import): use context manager for ZipFile
Extract archive processing into _process_archive to properly close the ZipFile via a context manager, preventing resource leaks. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 686d581 commit ddf8d6e

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

src/backend/core/services/outline_import.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def _upload_attachment(user, doc: models.Document, arcname: str, data: bytes) ->
9292

9393

9494
@transaction.atomic
95-
def process_outline_zip(user, zip_bytes: bytes) -> list[str]: # noqa: PLR0915
95+
def process_outline_zip(user, zip_bytes: bytes) -> list[str]:
9696
"""Process an Outline export zip and create Docs documents.
9797
9898
This function runs within an atomic transaction, ensuring that either all documents
@@ -101,8 +101,12 @@ def process_outline_zip(user, zip_bytes: bytes) -> list[str]: # noqa: PLR0915
101101
Returns the list of created document IDs (stringified UUIDs) corresponding to
102102
markdown-backed documents. Container folders used to rebuild hierarchy are not listed.
103103
"""
104-
archive = zipfile.ZipFile(io.BytesIO(zip_bytes))
104+
with zipfile.ZipFile(io.BytesIO(zip_bytes)) as archive:
105+
return _process_archive(user, archive)
105106

107+
108+
def _process_archive(user, archive: zipfile.ZipFile) -> list[str]: # noqa: PLR0915
109+
"""Process the opened archive and create documents."""
106110
# Basic Zip Slip protection: refuse paths that escape the archive root
107111
for name in archive.namelist():
108112
# Normalize to posix separators and check traversal

0 commit comments

Comments
 (0)