cas-serff-extractor / util_zip.py
pramodmisra's picture
Upload folder using huggingface_hub
1e8f25c verified
Raw
History Blame Contribute Delete
2.22 kB
"""Safe extraction of an uploaded SERFF filing ZIP.
Hardened for a public Space: rejects path traversal and absolute members, caps
entry count and total uncompressed size (zip-bomb guard), then returns the main
filing PDF (a top-level `*.pdf`, preferring one whose name matches the tracking #).
"""
from __future__ import annotations
import re
import zipfile
from pathlib import Path
MAX_ENTRIES = 200
MAX_TOTAL_BYTES = 200 * 1024 * 1024 # 200 MB uncompressed
TRACKING_RE = re.compile(r"[A-Z]{3,4}-\d{6,}")
def _is_safe(name: str) -> bool:
"""Reject absolute paths and parent-dir traversal."""
if name.startswith(("/", "\\")) or ".." in Path(name).parts:
return False
return True
def safe_unzip(zip_path: Path, dest: Path) -> Path:
"""Extract `zip_path` into `dest` safely; return the chosen main filing PDF."""
dest.mkdir(parents=True, exist_ok=True)
with zipfile.ZipFile(zip_path) as zf:
infos = zf.infolist()
assert len(infos) <= MAX_ENTRIES, f"zip has too many entries ({len(infos)})"
total = sum(i.file_size for i in infos)
assert total <= MAX_TOTAL_BYTES, f"zip too large uncompressed ({total} bytes)"
for info in infos: # bounded by MAX_ENTRIES
if info.is_dir() or not _is_safe(info.filename):
continue
target = dest / info.filename
target.parent.mkdir(parents=True, exist_ok=True)
with zf.open(info) as src, target.open("wb") as out:
out.write(src.read())
return _pick_main_pdf(dest)
def _pick_main_pdf(root: Path) -> Path:
"""Choose the main filing PDF: a top-level *.pdf, preferring the tracking-# one."""
top_pdfs = sorted(p for p in root.glob("*.pdf"))
if not top_pdfs:
any_pdfs = sorted(root.rglob("*.pdf"))
assert any_pdfs, "no PDF found in the uploaded zip"
return any_pdfs[0]
tracked = [p for p in top_pdfs if TRACKING_RE.search(p.stem)]
return tracked[0] if tracked else top_pdfs[0]
def tracking_from_name(pdf_path: Path) -> str:
"""Best-effort SERFF tracking number from the PDF filename."""
m = TRACKING_RE.search(pdf_path.stem)
return m.group(0) if m else pdf_path.stem