The PKCS#12 MAC and the PDF security handler's /U, R5/R6 and file-key
checks used plain equality, which stops at the first differing byte and
narrows a guess. Both crates now use a length-checked comparison that
folds every byte (the helper craft-offcrypto already used).
An archive could hold many individually allowed members whose combined
decompression was unbounded, because both readers passed
max_total_bytes: u64::MAX to craft-zip. Each now passes MAX_TOTAL (4 GiB)
and every entry read is charged to it.
craft-fig's declared-entry cap drops from 1,000,000 to 100,000 to match the
other ZIP readers; its images were already bounded by Limits::max_image_total.
The review of wordcraft#6345 found that text in code page 932, 936, 949 or 950
was read a byte at a time, each byte above ASCII becoming U+FFFD, and the file
opened with its characters gone. Such a file is refused as every Word 6.0/95
file was before, until the piece walk decodes byte pairs. The test that
asserted the replacement characters is replaced by one that asserts the
refusal and that the same text in a Western font still opens.
The module comment on the Word 6 stylesheet header now matches the reader (a
u16 header size, then the header), as the other review comment asked.
(cherry picked from commit 92f8dd24d1)
Ported from storytold/wordcraft#6317, #6335 and #6345 (one series): Word 6.0
and Word 95 files are read instead of refused: text in its code page (by font
charset, language and style), character and paragraph formatting, tables and
paragraph styles. Paths follow craft-doc-binary (craft-wordmodel,
craft-codepage, craft-cfb).
(cherry picked from commit aa220afc77)
The bridge fell back to decoding in the calling process whenever no worker
was configured, or the worker failed to start, which is exactly the case the
audit called out: acadrust allocates from sizes a hostile file declares, and
an allocation failure or stack overflow ends the process. Conversions are
now refused without a worker, a worker that cannot start is an error, and
allow_in_process() is the explicit opt-in for input known to be trusted.
The create() API exposed RC4-40 and RC4-128 behind a doc comment, so an app
could write files whose encryption protects nothing. create() now returns
Unsupported for both schemes; create_legacy() and
Document::set_encryption_legacy() are the explicit ways to write a file that
must stay readable by an old reader. Tests and the encrypt example, which
read and write every algorithm, use the legacy entry points.
Port of storytold/wordcraft#3821, whose reader code moved here with storytold/wordcraft#6603. Word's 0.08" cell margin comes from the Normal Table default table style; without a default table style a table that sets no margins (and whose style sets none) has zero margins. The zeros are kept as the table's own, also for the old properties of a tblPrChange, so they survive saving. w:default="on" now marks a default style too.
read_smf_lenient keeps what comes before MAX_EVENTS events or MAX_TRACKS
tracks and only says so in a warning. Those warnings are words, and at
most MAX_WARNINGS of them are kept: when earlier damage has filled them,
nothing tells the caller that the file was cut.
LenientRead gets over_limit, set whenever either limit left something
out, full warnings or not. A caller that refuses over-limit files, as
read_smf does, can now do so after a lenient read. LenientRead is
non_exhaustive, so the new field breaks no caller.
SonarCloud S7688 counts the POSIX [ tests in the Opus vector fetcher. The
script already needs bash for arrays and ${!ranges[@]}, so the tests use
[[ ... ]], which neither word-splits nor globs its operands.