Skip to content

Commit

Permalink
Fill FAT32 root directory clusters with zeros after allocation
Browse files Browse the repository at this point in the history
Fixes old data possibly being interpreted as directory entries
  • Loading branch information
rafalh committed Oct 25, 2024
1 parent 85f06e0 commit a276bb9
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ New features:
Bug fixes:
* Fix formatting volumes with size in range 4096-4199 KB
* Always respect `fat_type` from `FormatVolumeOptions`
* Fill FAT32 root directory clusters with zeros after allocation to avoid interpreting old data as directory entries

0.3.4 (2020-07-20)
------------------
Expand Down
2 changes: 1 addition & 1 deletion src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl<'a, IO: ReadWriteSeek, TP, OCC> File<'a, IO, TP, OCC> {
fn is_dir(&self) -> bool {
match self.entry {
Some(ref e) => e.inner().is_dir(),
None => false,
None => true, // root directory
}
}

Expand Down
41 changes: 32 additions & 9 deletions tests/format.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io;
use std::io::prelude::*;

use fatfs::StdIoWrapper;
use fatfs::{FatType, StdIoWrapper};
use fscommon::BufStream;

const KB: u64 = 1024;
Expand All @@ -10,6 +10,20 @@ const TEST_STR: &str = "Hi there Rust programmer!\n";

type FileSystem = fatfs::FileSystem<StdIoWrapper<BufStream<io::Cursor<Vec<u8>>>>>;

fn init_logger() {
let _ = env_logger::builder().is_test(true).try_init();
}

fn format_fs(opts: fatfs::FormatVolumeOptions, total_bytes: u64) -> FileSystem {
init_logger();
// Init storage to 0xD1 bytes (value has been choosen to be parsed as normal file)
let storage_vec: Vec<u8> = vec![0xD1_u8; total_bytes as usize];
let storage_cur = io::Cursor::new(storage_vec);
let mut buffered_stream = fatfs::StdIoWrapper::from(BufStream::new(storage_cur));
fatfs::format_volume(&mut buffered_stream, opts).expect("format volume");
fatfs::FileSystem::new(buffered_stream, fatfs::FsOptions::new()).expect("open fs")
}

fn basic_fs_test(fs: &FileSystem) {
let stats = fs.stats().expect("stats");
if fs.fat_type() == fatfs::FatType::Fat32 {
Expand Down Expand Up @@ -60,14 +74,7 @@ fn basic_fs_test(fs: &FileSystem) {
}

fn test_format_fs(opts: fatfs::FormatVolumeOptions, total_bytes: u64) -> FileSystem {
let _ = env_logger::builder().is_test(true).try_init();
// Init storage to 0xD1 bytes (value has been choosen to be parsed as normal file)
let storage_vec: Vec<u8> = vec![0xD1_u8; total_bytes as usize];
let storage_cur = io::Cursor::new(storage_vec);
let mut buffered_stream = fatfs::StdIoWrapper::from(BufStream::new(storage_cur));
fatfs::format_volume(&mut buffered_stream, opts).expect("format volume");

let fs = fatfs::FileSystem::new(buffered_stream, fatfs::FsOptions::new()).expect("open fs");
let fs = format_fs(opts, total_bytes);
basic_fs_test(&fs);
fs
}
Expand Down Expand Up @@ -135,3 +142,19 @@ fn test_format_volume_label_and_id() {
);
assert_eq!(fs.volume_id(), 1234);
}

#[test]
fn test_zero_root_dir_clusters() {
init_logger();
let total_bytes = 33 * MB;
let opts = fatfs::FormatVolumeOptions::new().fat_type(FatType::Fat32);
let fs = format_fs(opts, total_bytes);
let root_dir = fs.root_dir();

// create a bunch of files to force allocation of second root directory cluster (64 is combined size of LFN + SFN)
let files_to_create = fs.cluster_size() as usize / 64 + 1;
for i in 0..files_to_create {
root_dir.create_file(&format!("f{}", i)).unwrap();
}
assert_eq!(root_dir.iter().count(), files_to_create);
}

0 comments on commit a276bb9

Please sign in to comment.