ntfs_core/error.rs
1//! Crate-wide error type.
2
3/// Errors produced while parsing NTFS structures.
4#[derive(Debug, thiserror::Error)]
5pub enum NtfsError {
6 /// The input slice was shorter than the structure requires.
7 #[error("input too short for {what}: need {need} bytes, got {got}")]
8 TooShort {
9 what: &'static str,
10 need: usize,
11 got: usize,
12 },
13
14 /// The OEM ID at offset 3 was not `b"NTFS "`.
15 #[error("not an NTFS volume: OEM ID is {0:x?}, expected \"NTFS \"")]
16 BadOemId([u8; 8]),
17
18 /// Bytes-per-sector is not a power of two in the range 256..=4096.
19 #[error("invalid bytes-per-sector: {0} (must be a power of two in 256..=4096)")]
20 BadBytesPerSector(u16),
21
22 /// Sectors-per-cluster is zero or not a power of two.
23 #[error("invalid sectors-per-cluster encoding: {0:#04x}")]
24 BadSectorsPerCluster(u8),
25
26 /// The clusters-per-file-record-segment byte encodes an out-of-range size.
27 #[error("invalid MFT record size encoding: byte {0:#04x}")]
28 BadRecordSize(u8),
29
30 /// The clusters-per-index-buffer byte encodes an out-of-range size.
31 #[error("invalid index record size encoding: byte {0:#04x}")]
32 BadIndexRecordSize(u8),
33
34 /// An MFT record's signature was neither `FILE` nor `BAAD`.
35 #[error("bad MFT record signature: {0:x?} (expected \"FILE\" or \"BAAD\")")]
36 BadRecordSignature([u8; 4]),
37
38 /// An update-sequence fixup did not match the Update Sequence Number — the
39 /// record was torn across a sector boundary, or has been tampered with.
40 #[error("fixup mismatch in sector {sector}: expected USN {expected:#06x}, found {found:#06x}")]
41 FixupMismatch {
42 sector: usize,
43 expected: u16,
44 found: u16,
45 },
46
47 /// The update sequence array is malformed (offset/count out of bounds).
48 #[error("malformed update sequence array: {0}")]
49 BadUpdateSequence(&'static str),
50
51 /// An attribute is corrupt or would read out of bounds — rejected rather
52 /// than trusted (defends against crafted records).
53 #[error("corrupt attribute at offset {offset}: {detail}")]
54 BadAttribute { offset: usize, detail: &'static str },
55
56 /// A data runlist is malformed (bad field size, truncated, or overflowing).
57 #[error("malformed runlist: {0}")]
58 BadRunlist(&'static str),
59
60 /// A directory index node or entry is malformed.
61 #[error("malformed index: {0}")]
62 BadIndex(&'static str),
63
64 /// LZNT1-compressed data is malformed.
65 #[error("malformed compressed data: {0}")]
66 BadCompression(&'static str),
67
68 /// An `$ATTRIBUTE_LIST` entry is malformed.
69 #[error("malformed attribute list: {0}")]
70 BadAttributeList(&'static str),
71
72 /// A path component was not found.
73 #[error("path not found: {0}")]
74 NotFound(String),
75
76 /// A path component that should be a directory is not one.
77 #[error("not a directory: {0}")]
78 NotADirectory(String),
79
80 /// A structure declared a size that would require an unreasonable
81 /// allocation — refused rather than attempted (defends against crafted
82 /// sizes / allocation bombs).
83 #[error("refusing to allocate {bytes} bytes")]
84 TooLarge { bytes: u64 },
85
86 /// A `$UsnJrnl` change-journal record was malformed (bad length, truncated,
87 /// or an unsupported version) — rejected rather than trusted.
88 #[error("malformed USN record: {0}")]
89 Usn(String),
90
91 /// An underlying I/O error.
92 #[error("I/O error: {0}")]
93 Io(#[from] std::io::Error),
94}
95
96/// Convenience alias.
97pub type Result<T> = std::result::Result<T, NtfsError>;