Skip to content

Decide whether to remove the deprecated fragment parser (parse_record_to_fragment) #572

Description

@githubrobbi

Decision to revisit, not a bug

io::parser::parse_record_to_fragment (plus fragment_extension::parse_extension_to_fragment, ~680 lines) is #[deprecated] and has zero callers in the workspace — only the two re-exports (io.rs:45, io/parser/mod.rs:16) and tests. The live parsers are io::parser::unified::process_record (bulk load) and parse::direct_index::parse_record_to_index (USN incremental).

Deleting it was considered and deliberately rejected for now:

  • uffs-forensics is a planned in-repo consumer, and carving partial/fragmented records is squarely its remit. Deleting hard-won untrusted-byte parsing and rebuilding it later, worse, is the bad trade. Correct-but-dormant beats deleted-and-rewritten.
  • uffs-mft is consumable from git by third parties. #[deprecated] is the right signal; the semver-correct path is deprecate then remove in a breaking release, with its own release note — not a silent pub removal riding along in an unrelated PR.
  • Confirmed uffs-products does not use it: zero hits for parse_record_to_fragment, MftIndexFragment, fragment_extension, merge_fragments.

Revisit criteria

Around 2027-01, or once uffs-forensics has shipped — whichever is first:

  • If uffs-forensics shipped and does not use it, and it is still callerless: remove it in a breaking release, with a release note. The argument is then a fact rather than a guess.
  • If uffs-forensics (or any consumer) does use it: drop the #[deprecated], give it real coverage, and treat it as supported.

Context

Found while adding the NTFS 3.0+ $SI fields to ExtendedStandardInfo. Two related fixes already landed and are not blocked on this decision:

  • fix(mft): stop zeroing usn/security_id/owner_id in the fragment parser — the path hand-rolled a 36-byte NTFS 1.2 $STANDARD_INFORMATION read regardless of the record's real $SI size, silently zeroing those three fields on every modern volume. Now routed through the shared, fuzz-hardened parse_standard_info_full, with a regression pin.
  • The stale #[expect(clippy::too_many_lines, reason = "...performance-critical hot path")] reason string, false since the fragment-merge rewrite, now states the real status. A reason-string that is actively false is worse than none: the next reader treats a dead function as load-bearing, which is how this survived.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions