Skip to content

Commit 02e4974

Browse files
committed
Merge branch 'fix-f-drive-parity'
2 parents e2e59f1 + 3abf5b9 commit 02e4974

File tree

4 files changed

+32
-15
lines changed

4 files changed

+32
-15
lines changed

crates/uffs-mft/src/index/builder.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -465,17 +465,17 @@ impl MftIndex {
465465
tracing::debug!("[TRIP] MftIndex::from_parsed_records -> Phase 2: ExtensionIndex::build");
466466
index.extension_index = Some(ExtensionIndex::build(&index));
467467

468-
// 2. Compute tree metrics for directory statistics (Phase 5)
469-
// CRITICAL: Must run BEFORE sorting to match C++ MFT insertion order.
470-
// Hardlink delta rounding depends on child traversal order.
471-
tracing::debug!("[TRIP] MftIndex::from_parsed_records -> Phase 5: compute_tree_metrics");
472-
index.compute_tree_metrics();
473-
474-
// 3. Sort directory children for natural ordering (Phase 4)
475-
// This is purely for display/output - tree metrics must run first.
468+
// 2. Sort directory children for natural ordering (Phase 4)
469+
// CRITICAL: Must run BEFORE computing tree metrics for correct size
470+
// aggregation.
476471
tracing::debug!("[TRIP] MftIndex::from_parsed_records -> Phase 4: sort_directory_children");
477472
index.sort_directory_children();
478473

474+
// 3. Compute tree metrics for directory statistics (Phase 5)
475+
// Must run AFTER sorting - depends on sorted child traversal order.
476+
tracing::debug!("[TRIP] MftIndex::from_parsed_records -> Phase 5: compute_tree_metrics");
477+
index.compute_tree_metrics();
478+
479479
// 4. Set forensic mode flag if any forensic records were included
480480
index.forensic_mode = has_forensic_records;
481481

crates/uffs-mft/src/index/merge.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ impl MftIndex {
5454
debug!("🔨 Building extension index...");
5555
self.extension_index = Some(ExtensionIndex::build(self));
5656

57-
debug!("🔨 Computing tree metrics...");
58-
self.compute_tree_metrics();
59-
6057
debug!("🔨 Sorting directory children...");
6158
self.sort_directory_children();
6259

60+
debug!("🔨 Computing tree metrics...");
61+
self.compute_tree_metrics();
62+
6363
debug!("✅ Post-processing complete");
6464
}
6565

crates/uffs-mft/src/io/parser/index.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ pub fn parse_record_to_index(data: &[u8], frs: u64, index: &mut crate::index::Mf
121121
break;
122122
}
123123

124+
// Validate that the attribute's declared length fits within the record data
125+
// This prevents reading past record boundaries when attributes are truncated
126+
if offset + attr_header.length as usize > data.len() {
127+
break; // Attribute extends past record — stop processing
128+
}
129+
124130
let attr_type = AttributeType::from_u32(attr_header.type_code);
125131
match attr_type {
126132
Some(AttributeType::StandardInformation) => {
@@ -217,7 +223,9 @@ pub fn parse_record_to_index(data: &[u8], frs: u64, index: &mut crate::index::Mf
217223
);
218224
lowest_vcn == 0
219225
} else {
220-
false // Can't verify, skip to be safe
226+
// Can't read LowestVCN — assume primary (LowestVCN == 0 is common case)
227+
// This prevents skipping valid $DATA attributes near record boundaries
228+
true
221229
}
222230
};
223231

@@ -245,6 +253,15 @@ pub fn parse_record_to_index(data: &[u8], frs: u64, index: &mut crate::index::Mf
245253
.unwrap_or([0; 8]),
246254
);
247255
(size, allocated)
256+
} else if alloc_offset + 8 <= data.len() {
257+
// Can read AllocatedSize but not DataSize — use AllocatedSize for both
258+
// This handles attributes truncated near record boundary
259+
let allocated = u64::from_le_bytes(
260+
data[alloc_offset..alloc_offset + 8]
261+
.try_into()
262+
.unwrap_or([0; 8]),
263+
);
264+
(allocated, allocated)
248265
} else {
249266
(0, 0)
250267
}

crates/uffs-mft/src/reader/persistence.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,12 +609,12 @@ impl MftReader {
609609
}
610610
}
611611

612-
// Compute tree metrics
613-
index.compute_tree_metrics();
614-
615612
// Sort directory children
616613
index.sort_directory_children();
617614

615+
// Compute tree metrics
616+
index.compute_tree_metrics();
617+
618618
let parse_time = parse_start.elapsed();
619619

620620
info!(

0 commit comments

Comments
 (0)