fix(ole): repair the zero-filled MiniFAT Apple's Cocoa exporter emits - #42
Open
mathurshubham wants to merge 1 commit into
Open
fix(ole): repair the zero-filled MiniFAT Apple's Cocoa exporter emits#42mathurshubham wants to merge 1 commit into
mathurshubham wants to merge 1 commit into
Conversation
.doc files written by TextEdit ("Save as Word 97") and `textutil
-convert doc` zero-fill the MiniFAT instead of terminating chains with
FREESECT/ENDOFCHAIN, so every entry reads as "next is mini sector 0"
and cfb rejects the file ("Malformed MiniFAT: mini sector 0 pointed to
twice") before any content is seen.
An all-zero MiniFAT cannot occur in a valid file - entry 0 would point
at itself - so that exact shape is safe to treat as the writer defect:
rebuild the chains from the directory entries (each mini stream below
the cutoff owns contiguous sectors from its start, sized from the entry)
and retry the open. The repair is gated on the full signature - CFB
magic, no external DIFAT, every MiniFAT entry zero, no overlapping
rebuilt chains - and any other failure keeps its original error.
doc, ppt, and content detection all open through the new helper, so a
TextEdit .doc is both detected from bytes and converted. The streams
the parsers need live in regular sectors; the repair only has to make
the container open.
Fixes firecrawl#37
|
hi i would like to work on this issue |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #37.
Diagnosis
Dissected the reporter's file (and a locally generated
textutil -convert doctwin): Apple's Cocoa exporter zero-fills the MiniFAT sector insteadof writing
FREESECT/ENDOFCHAINmarkers. Every entry then reads as"next is mini sector 0", which is the doubly-linked chain
cfbrejects("mini sector 0 pointed to twice") before any content is visible.
Everything the
.docparser needs lives in regular sectors — the file isfully convertible; only the container refuses to open.
The fix
A repair pass in
shared/binary.rs, used by every OLE2 open site (doc, ppt,and byte-content detection): when
cfbrefuses the file, check for thedefect's exact signature and rebuild the MiniFAT from the directory entries,
then retry the open once.
Safety is the design center — an all-zero MiniFAT is impossible in a
valid file (entry 0 would point at itself), so the repair can never fire on
a well-formed one. It is further gated on:
surfaces unchanged;
ceil(size / 64)contiguous sectors from its start, which is howsequential writers allocate them) — ambiguity aborts the repair.
Version-3 (512-byte) and version-4 (4096-byte sector) containers both
handled — sector N lives at
(N + 1) << sector_shift.Verification
textutil -stdin -convert docon macOS 26) converts:Alpha paragraph. / Beta paragraph.— and a second, larger TextEdit fileas well. Detection from bytes now also identifies these as
.doc.malformed/zeroed-minifat--recovers.doc— the committedLibreOffice
text.docwith its MiniFAT zeroed by the generator (purebyte mutation, no macOS needed in CI). Its snapshot is byte-identical
to the pristine
text.docsnapshot, proving full recovery.(mini-stream and regular alike, v4 container from
cfb::create); validfiles bypass the repair; non-zero MiniFAT corruption keeps its original
error; non-OLE bytes fail cleanly.
cargo fmt --check,clippy --workspace --all-targets --all-features -D warnings,cargo test --lockedall green; the only snapshot in thediff is the new fixture's.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.