Skip to content

Commit 819a624

Browse files
committed
Fix issue #74
Map ROOT_DIR (0xFFFF_FFFC) to an actual cluster number, so if you go off the end of the first cluster of the root directory on FAT32, the code no longer crashes trying to convert the ROOT_DIR magic cluster number into a disk offset.
1 parent fec3af5 commit 819a624

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/fat/volume.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ impl FatVolume {
179179
where
180180
D: BlockDevice,
181181
{
182+
if cluster.0 > (u32::MAX / 4) {
183+
panic!("next_cluster called on invalid cluster {:x?}", cluster);
184+
}
182185
match &self.fat_specific_info {
183186
FatSpecificInfo::Fat16(_fat16_info) => {
184187
let fat_offset = cluster.0 * 2;
@@ -360,19 +363,24 @@ impl FatVolume {
360363
FatSpecificInfo::Fat32(fat32_info) => {
361364
// All directories on FAT32 have a cluster chain but the root
362365
// dir starts in a specified cluster.
363-
let mut first_dir_block_num = match dir.cluster {
364-
ClusterId::ROOT_DIR => self.cluster_to_block(fat32_info.first_root_dir_cluster),
365-
_ => self.cluster_to_block(dir.cluster),
366+
let mut current_cluster = match dir.cluster {
367+
ClusterId::ROOT_DIR => Some(fat32_info.first_root_dir_cluster),
368+
_ => Some(dir.cluster),
366369
};
367-
let mut current_cluster = Some(dir.cluster);
370+
let mut first_dir_block_num = self.cluster_to_block(dir.cluster);
368371
let mut blocks = [Block::new()];
369372

370373
let dir_size = BlockCount(u32::from(self.blocks_per_cluster));
374+
// Walk the cluster chain until we run out of clusters
371375
while let Some(cluster) = current_cluster {
376+
// Loop through the blocks in the cluster
372377
for block in first_dir_block_num.range(dir_size) {
378+
// Read a block of directory entries
373379
block_device
374380
.read(&mut blocks, block, "read_dir")
375381
.map_err(Error::DeviceError)?;
382+
// Are any entries in the block we just loaded blank? If so
383+
// we can use them.
376384
for entry in 0..Block::LEN / OnDiskDirEntry::LEN {
377385
let start = entry * OnDiskDirEntry::LEN;
378386
let end = (entry + 1) * OnDiskDirEntry::LEN;
@@ -397,6 +405,8 @@ impl FatVolume {
397405
}
398406
}
399407
}
408+
// Well none of the blocks in that cluster had any space in
409+
// them, let's fetch another one.
400410
let mut block_cache = BlockCache::empty();
401411
current_cluster =
402412
match self.next_cluster(block_device, cluster, &mut block_cache) {
@@ -412,6 +422,8 @@ impl FatVolume {
412422
_ => None,
413423
};
414424
}
425+
// We ran out of clusters in the chain, and apparently we weren't
426+
// able to make the chain longer, so the disk must be full.
415427
Err(Error::NotEnoughSpace)
416428
}
417429
}

0 commit comments

Comments
 (0)