阅读文本 / Reading text
This paper uses synthetic samples to demonstrate the processing method. The code has been verified using examples in an isolated environment; this does not guarantee effectiveness for all real files or products. Before processing important files, please retain the original copies and verify them against the boundaries and acceptance criteria specified in the text.
DOCX is essentially a set of ZIP entries, and EPUB also uses a ZIP container. Receiving a very small compressed file does not mean it will remain small after decompression. At the entry point, limits should be imposed on the compressed size, the number of entries, the size of individual files, and the total expanded size—rather than waiting until memory is exhausted to determine that the file is abnormal.
first checks the directory table, but do not treat it as the final guarantee
ZipInfo
provides the declared size and the compressed size, making it suitable for preliminary filtering. During actual decompression, the bytes already read must still be accumulated, and time and memory budgets must be set. The directory table can help reject entries in advance, but it cannot replace runtime constraints.
An example of an uncompressed pre-sieve
from io import BytesIO
from pathlib import PurePosixPath
from zipfile import ZipFile, ZIP_DEFLATED
def inspect(raw, max_entries=10, max_total=4096):
if len(raw) > 4096:
raise ValueError("compressed input budget")
with ZipFile(BytesIO(raw)) as z:
items = z.infolist()
if len(items) > max_entries:
raise ValueError("entry count budget")
total, seen = 0, set()
for item in items:
name = item.filename
path = PurePosixPath(name)
if (path.is_absolute() or ".." in path.parts or
"\\" in name or ":" in name or name in seen):
raise ValueError("unsafe or duplicate name")
seen.add(name)
total += item.file_size
if total > max_total:
raise ValueError("expanded budget")
return len(items), total
def sample(name, data):
out = BytesIO()
with ZipFile(out, "w", ZIP_DEFLATED) as z:
z.writestr(name, data)
return out.getvalue()
assert inspect(sample("word/document.xml", b"<doc/>")) == (1, 6)
for raw in [sample("../escape", b"x"), sample("large", b"x" * 5000)]:
try:
inspect(raw)
except ValueError:
pass
else:
raise AssertionError("unsafe archive accepted")
These budgets are very small values chosen to demonstrate the rejection path and should not be directly replicated as production limits. The example does not invoke
extractall
, nor does it perform ZIP entry writing, and therefore does not claim to be a fully secure decompressor. Encryption of entries, symbolic links, nested archives, and the parser’s own resource consumption all require separate policies.
provides the user with actionable information upon rejection
trigger condition
explains to the user
internal record
total expansion exceeds the budget
file becomes excessively large after expansion
constraint name and observed value
duplicate entry name
container structure is unclear
entry index, without recording the full text
out-of-bounds path
file structure is not supported
Security Incident Correlation ID
container damaged
Please re-export the file
parsing exception type
Do not disable all restrictions just for compatibility
Even reasonably large documents may exceed the budget; therefore, an independent queue for large files or a manual processing entry point should be provided. Increasing a tenant’s business quota does not mean allowing all tasks to decompress indefinitely. Restrictions must be implemented in conjunction with execution isolation, rather than merely being displayed next to the upload button.
Translation failure requires determining at which layer it occurs.
is preparing to send to
OmniDoc (product entry point)
When submitting a document, first separate container corruption from translation failures. For a DOCX file that cannot even be parsed by XML, the issue may lie in the input preparation stage. A clear pre-check report enables users to determine whether they should re-export the file, compress images, or contact the translation service for troubleshooting.
Reference:
Python zipfile
。
- 1 -
Updated 2026-10-08