From 6b18dfd626f3b43114a8068d20536b996d90c319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Sat, 23 Sep 2017 00:22:31 +0200 Subject: [PATCH] Don't read past end of file. --- src/dir.rs | 26 ++++++++++++++++---------- src/file.rs | 10 ++++++++-- src/fs.rs | 17 ++++++++++++----- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/dir.rs b/src/dir.rs index 8dc91c5..9fed0e8 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -84,21 +84,27 @@ impl FatDirEntry { impl FatFileSystem { pub fn read_dir(&mut self, dir: &mut FatFile) -> io::Result> { - - let mut cur = Cursor::new(vec![0; 512]); - self.read(dir, cur.get_mut())?; - let mut entries = Vec::new(); + let mut buf = vec![0; self.get_cluster_size() as usize]; loop { - let entry = read_dir_entry(&mut cur)?; - if entry.name[0] == 0 { - break; // end of dir + let size = self.read(dir, &mut buf)?; + if size == 0 { + break; } - if entry.name[0] == 0xE5 { - continue; // deleted + + let mut cur = Cursor::new(&buf[..size]); + loop { + let entry = read_dir_entry(&mut cur)?; + if entry.name[0] == 0 { + break; // end of dir + } + if entry.name[0] == 0xE5 { + continue; // deleted + } + entries.push(entry); } - entries.push(entry); } + Ok(entries) } } diff --git a/src/file.rs b/src/file.rs index 59a8d80..f599f84 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,4 +1,6 @@ +use std::cmp; use std::io::prelude::*; +use std::io::SeekFrom; use std::io; use fs::FatFileSystem; @@ -27,8 +29,12 @@ impl FatFileSystem { } pub fn read(&mut self, file: &mut FatFile, buf: &mut [u8]) -> io::Result { - self.seek_to_sector(file.first_sector as u64)?; - let size = self.rdr.read(buf)?; + let offset = self.offset_from_sector(file.first_sector) + file.offset as u64; + let mut read_size = cmp::min((file.size - file.offset) as usize, buf.len()); + // FIXME: allow only one cluster for now + read_size = cmp::min(read_size, (self.get_cluster_size() - file.offset) as usize); + self.rdr.seek(SeekFrom::Start(offset))?; + let size = self.rdr.read(&mut buf[..read_size])?; file.offset += size as u32; Ok(size) } diff --git a/src/fs.rs b/src/fs.rs index 54fcd5c..ebe78d4 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -1,5 +1,5 @@ use std::io::prelude::*; -use std::io::{Error, ErrorKind, SeekFrom}; +use std::io::{Error, ErrorKind}; use std::io; use std::str; use byteorder::{LittleEndian, ReadBytesExt}; @@ -189,15 +189,22 @@ impl FatFileSystem { Ok(boot) } - pub fn seek_to_sector(&mut self, sector: u64) -> io::Result<()> { - self.rdr.seek(SeekFrom::Start(sector*512))?; - Ok(()) + // pub(crate) fn offset_from_cluster(&self, cluser: u32) -> u64 { + // self.offset_from_sector(self.sector_from_cluster(cluser)) + // } + + pub(crate) fn offset_from_sector(&self, sector: u32) -> u64 { + (sector as u64) * self.boot.bpb.bytes_per_sector as u64 } - pub fn sector_from_cluster(&self, cluster: u32) -> u32 { + pub(crate) fn sector_from_cluster(&self, cluster: u32) -> u32 { ((cluster - 2) * self.boot.bpb.sectors_per_cluster as u32) + self.first_data_sector } + pub(crate) fn get_cluster_size(&self) -> u32 { + self.boot.bpb.sectors_per_cluster as u32 * self.boot.bpb.bytes_per_sector as u32 + } + pub(crate) fn get_root_dir_sector(&self) -> u32 { match self.fat_type { FatType::Fat12 | FatType::Fat16 => self.first_data_sector - self.root_dir_sectors,