Skip to main content

fat/
lib.rs

1//! fat-core: pure-Rust forensic reader for FAT12/16/32 and exFAT.
2//!
3//! Imported as `fat` (`[lib] name = "fat"`). [`FatFs::open`] auto-detects the
4//! variant from the boot sector and exposes uniform navigation across all four.
5
6#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
7
8mod boot;
9mod bytes;
10mod dirent;
11mod error;
12mod exfat;
13mod fat;
14mod fs;
15mod time;
16#[cfg(feature = "vfs")]
17mod vfs;
18
19pub use boot::{FatVariant, Geometry};
20pub use error::{FatError, Result};
21pub use exfat::{boot_checksum, parse_boot as parse_exfat_boot};
22pub use fs::{FatFs, FileId, Node};
23pub use time::FatTimestamp;
24
25/// Entry points for `cargo-fuzz` targets only — compiled solely under
26/// `--cfg fuzzing`, so they never widen the public API or affect coverage. Each
27/// drives one parsed structure over arbitrary bytes; the invariant is
28/// "must not panic". NOT a stable API.
29#[cfg(fuzzing)]
30#[doc(hidden)]
31pub mod __fuzz {
32    use crate::boot::{FatVariant, Geometry};
33
34    /// FAT12/16/32 boot sector (BPB) parse.
35    pub fn parse_bpb(data: &[u8]) {
36        let _ = Geometry::parse(data);
37    }
38
39    /// exFAT main boot sector parse.
40    pub fn parse_exfat_boot(data: &[u8]) {
41        let _ = crate::exfat::parse_boot(data);
42    }
43
44    /// FAT 8.3 / VFAT long-name directory decode.
45    pub fn parse_dir_entry(data: &[u8]) {
46        let _ = crate::dirent::parse_directory(data);
47    }
48
49    /// exFAT typed directory-entry-set decode.
50    pub fn parse_exfat_dir(data: &[u8]) {
51        let _ = crate::exfat::parse_directory(data);
52    }
53
54    /// FAT cluster-chain following (variant + start cluster derived from input).
55    pub fn walk_fat_chain(data: &[u8]) {
56        if data.len() < 5 {
57            return;
58        }
59        let variant = match data[0] & 3 {
60            0 => FatVariant::Fat12,
61            1 => FatVariant::Fat16,
62            2 => FatVariant::Fat32,
63            _ => FatVariant::ExFat,
64        };
65        let start = u32::from_le_bytes([data[1], data[2], data[3], data[4]]);
66        let _ = crate::fat::follow_chain(&data[5..], variant, start, 100_000);
67    }
68}