From a276bb95c35edcaedb26c065eb60ee76499261e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Sat, 26 Oct 2024 00:27:46 +0200 Subject: [PATCH] Fill FAT32 root directory clusters with zeros after allocation Fixes old data possibly being interpreted as directory entries --- CHANGELOG.md | 1 + src/file.rs | 2 +- tests/format.rs | 41 ++++++++++++++++++++++++++++++++--------- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a9103d..ee8127e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) ------------------ diff --git a/src/file.rs b/src/file.rs index 5df3a29..6e588e9 100644 --- a/src/file.rs +++ b/src/file.rs @@ -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 } } diff --git a/tests/format.rs b/tests/format.rs index b5a4e30..9acbb3f 100644 --- a/tests/format.rs +++ b/tests/format.rs @@ -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; @@ -10,6 +10,20 @@ const TEST_STR: &str = "Hi there Rust programmer!\n"; type FileSystem = fatfs::FileSystem>>>>; +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 = 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 { @@ -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 = 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 } @@ -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); +}