{"record":{"id":"da79f5280b72a63c","repo":"HKUDS/DeepTutor","slug":"mineru-archive-exceeds-the-size-limit","errorCode":null,"errorMessage":"MinerU archive exceeds the size limit.","messagePattern":"MinerU archive exceeds the size limit\\.","errorType":"exception","errorClass":"MinerUError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/parsing/engines/mineru/cloud.py","lineNumber":347,"sourceCode":"    total = 0\n    try:\n        with zipfile.ZipFile(io.BytesIO(archive_bytes)) as archive:\n            members = [m for m in archive.infolist() if not m.is_dir()]\n            if len(members) > _MAX_ENTRIES:\n                raise MinerUError(f\"MinerU archive has too many entries ({len(members)}).\")\n            for member in members:\n                # Collapse to a POSIX-relative path and reject traversal.\n                rel = Path(member.filename.replace(\"\\\\\", \"/\"))\n                if rel.is_absolute() or \"..\" in rel.parts:\n                    logger.warning(\"Skipping unsafe zip member: %s\", member.filename)\n                    continue\n                dest = (target_root / rel).resolve()\n                if target_root not in dest.parents and dest != target_root:\n                    logger.warning(\"Skipping zip member escaping root: %s\", member.filename)\n                    continue\n                total += member.file_size\n                if total > _MAX_TOTAL_BYTES:\n                    raise MinerUError(\"MinerU archive exceeds the size limit.\")\n                dest.parent.mkdir(parents=True, exist_ok=True)\n                with archive.open(member) as src, open(dest, \"wb\") as out:\n                    out.write(src.read())\n    except zipfile.BadZipFile as exc:\n        raise MinerUError(f\"MinerU returned an invalid archive: {exc}\") from exc\n\n\n__all__ = [\"parse_cloud\", \"verify_credentials\"]\n","sourceCodeStart":329,"sourceCodeEnd":356,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/parsing/engines/mineru/cloud.py#L329-L356","documentation":"Raised by _extract_archive when the cumulative uncompressed size of members extracted from a MinerU-result zip exceeds _MAX_TOTAL_BYTES. It is a defensive guard against zip bombs served by the MinerU cloud API. Extraction is aborted mid-stream.","triggerScenarios":"Calling parse_cloud on a document whose returned archive's summed member.file_size values exceed _MAX_TOTAL_BYTES (accumulated in `total` during iteration); also exercised directly by test_extract_archive_rejects_zip_slip-style tests with oversized fixtures.","commonSituations":"A malicious or corrupted result archive from the MinerU cloud service (zip bomb), very large scanned documents with many high-resolution images, or a stale _MAX_TOTAL_BYTES constant after a MinerU API change.","solutions":["Increase _MAX_TOTAL_BYTES if your documents legitimately produce larger archives","Check the MinerU job output size (e.g. disable image extraction / lower DPI) before downloading","Inspect the archive manually (unzip -l) to confirm whether the size is legitimate or a bomb","If malicious input is suspected, reject the document and re-run the MinerU job"],"exampleFix":"// before\n_MAX_TOTAL_BYTES = 256 * 1024 * 1024\n\n// after (if large scans are expected)\n_MAX_TOTAL_BYTES = 512 * 1024 * 1024","handlingStrategy":"validation","validationCode":"import zipfile\n\ndef archive_total_size_ok(path, limit=_MAX_TOTAL_BYTES) -> bool:\n    with zipfile.ZipFile(path) as z:\n        return sum(i.file_size for i in z.infolist()) <= limit","typeGuard":null,"tryCatchPattern":"try:\n    parse_cloud(...)\nexcept MinerUError as e:\n    if 'size limit' in str(e): reduce_image_quality_and_retry()\n    else: raise","preventionTips":["Pre-check the uncompressed archive size before extraction","Cap requested image DPI/quality in the MinerU job config"],"tags":["mineru","zip-bomb","size-limit","parsing"],"backgroundTag":"archive-size-limit-exceeded","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}