From cf3256bfdaf82aa040bba672ee1df54e1a94154c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Sat, 8 Dec 2018 19:33:56 +0100 Subject: [PATCH] fix: clear directory returned from create_dir method Previous implementation did not zero allocated cluster so created directory could have garbage contents. Bug exists in code since version 0.2 and all code using create_dir is affected. This commit also improves tests of volume formatting so a dirty partition is used allowing to detect bugs like this. --- src/dir.rs | 2 +- src/file.rs | 13 +------------ src/fs.rs | 13 ++++++++++--- tests/format.rs | 5 +++-- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/dir.rs b/src/dir.rs index 6619204..1f4e3a8 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -236,7 +236,7 @@ impl<'a, T: ReadWriteSeek + 'a> Dir<'a, T> { // directory does not exist - create it DirEntryOrShortName::ShortName(short_name) => { // alloc cluster for directory data - let cluster = self.fs.alloc_cluster(None)?; + let cluster = self.fs.alloc_cluster(None, true)?; // create entry in parent directory let sfn_entry = self.create_sfn_entry(short_name, FileAttributes::DIRECTORY, Some(cluster)); let entry = self.write_entry(name, sfn_entry)?; diff --git a/src/file.rs b/src/file.rs index 2b5b788..d909032 100644 --- a/src/file.rs +++ b/src/file.rs @@ -261,22 +261,11 @@ impl<'a, T: ReadWriteSeek> Write for File<'a, T> { Some(n) => n, None => { // end of chain reached - allocate new cluster - let new_cluster = self.fs.alloc_cluster(self.current_cluster)?; + let new_cluster = self.fs.alloc_cluster(self.current_cluster, self.is_dir())?; trace!("allocated cluser {}", new_cluster); if self.first_cluster.is_none() { self.set_first_cluster(new_cluster); } - if self.is_dir() { - // zero new directory cluster - trace!("zeroing directory cluster {}", new_cluster); - let abs_pos = self.fs.offset_from_cluster(new_cluster); - let mut disk = self.fs.disk.borrow_mut(); - disk.seek(SeekFrom::Start(abs_pos))?; - for _ in 0..cluster_size / 32 { - let zero = [0u8; 32]; - disk.write(&zero)?; - } - } new_cluster }, } diff --git a/src/fs.rs b/src/fs.rs index 1dd2842..d33417a 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -472,11 +472,18 @@ impl FileSystem { Ok(()) } - pub(crate) fn alloc_cluster(&self, prev_cluster: Option) -> io::Result { + pub(crate) fn alloc_cluster(&self, prev_cluster: Option, zero: bool) -> io::Result { trace!("alloc_cluster"); let hint = self.fs_info.borrow().next_free_cluster; - let mut fat = self.fat_slice(); - let cluster = alloc_cluster(&mut fat, self.fat_type, prev_cluster, hint, self.total_clusters)?; + let cluster = { + let mut fat = self.fat_slice(); + alloc_cluster(&mut fat, self.fat_type, prev_cluster, hint, self.total_clusters)? + }; + if zero { + let mut disk = self.disk.borrow_mut(); + disk.seek(SeekFrom::Start(self.offset_from_cluster(cluster)))?; + write_zeros(&mut *disk, self.cluster_size() as usize)?; + } let mut fs_info = self.fs_info.borrow_mut(); fs_info.set_next_free_cluster(cluster + 1); fs_info.add_free_clusters(-1); diff --git a/tests/format.rs b/tests/format.rs index b3a41c9..b3f2090 100644 --- a/tests/format.rs +++ b/tests/format.rs @@ -50,7 +50,8 @@ fn basic_fs_test(fs: &FileSystem) { fn test_format_fs(opts: fatfs::FormatVolumeOptions, total_bytes: u64) -> FileSystem { let _ = env_logger::try_init(); - let storage_vec: Vec = Vec::with_capacity(total_bytes as usize); + // Init storage to 0xD1 bytes (value has been choosen to be parsed as normal file) + let storage_vec: Vec = vec![0xD1u8; total_bytes as usize]; let storage_cur = io::Cursor::new(storage_vec); let mut buffered_stream = BufStream::new(storage_cur); fatfs::format_volume(&mut buffered_stream, opts).expect("format volume"); @@ -86,7 +87,7 @@ fn test_format_50mb() { #[test] -fn test_format_512mb() { +fn test_format_512mb_512sec() { let total_bytes = 2 * 1024 * MB; let opts = fatfs::FormatVolumeOptions::new((total_bytes / 512) as u32, 512); let fs = test_format_fs(opts, total_bytes);