Don't read past end of file.

This commit is contained in:
Rafał Harabień 2017-09-23 00:22:31 +02:00
parent dd23854cd5
commit 6b18dfd626
3 changed files with 36 additions and 17 deletions

View File

@ -84,11 +84,15 @@ impl FatDirEntry {
impl<T: Read+Seek> FatFileSystem<T> { impl<T: Read+Seek> FatFileSystem<T> {
pub fn read_dir(&mut self, dir: &mut FatFile) -> io::Result<Vec<FatDirEntry>> { pub fn read_dir(&mut self, dir: &mut FatFile) -> io::Result<Vec<FatDirEntry>> {
let mut cur = Cursor::new(vec![0; 512]);
self.read(dir, cur.get_mut())?;
let mut entries = Vec::new(); let mut entries = Vec::new();
let mut buf = vec![0; self.get_cluster_size() as usize];
loop {
let size = self.read(dir, &mut buf)?;
if size == 0 {
break;
}
let mut cur = Cursor::new(&buf[..size]);
loop { loop {
let entry = read_dir_entry(&mut cur)?; let entry = read_dir_entry(&mut cur)?;
if entry.name[0] == 0 { if entry.name[0] == 0 {
@ -99,6 +103,8 @@ impl<T: Read+Seek> FatFileSystem<T> {
} }
entries.push(entry); entries.push(entry);
} }
}
Ok(entries) Ok(entries)
} }
} }

View File

@ -1,4 +1,6 @@
use std::cmp;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::SeekFrom;
use std::io; use std::io;
use fs::FatFileSystem; use fs::FatFileSystem;
@ -27,8 +29,12 @@ impl<T: Read+Seek> FatFileSystem<T> {
} }
pub fn read(&mut self, file: &mut FatFile, buf: &mut [u8]) -> io::Result<usize> { pub fn read(&mut self, file: &mut FatFile, buf: &mut [u8]) -> io::Result<usize> {
self.seek_to_sector(file.first_sector as u64)?; let offset = self.offset_from_sector(file.first_sector) + file.offset as u64;
let size = self.rdr.read(buf)?; 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; file.offset += size as u32;
Ok(size) Ok(size)
} }

View File

@ -1,5 +1,5 @@
use std::io::prelude::*; use std::io::prelude::*;
use std::io::{Error, ErrorKind, SeekFrom}; use std::io::{Error, ErrorKind};
use std::io; use std::io;
use std::str; use std::str;
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{LittleEndian, ReadBytesExt};
@ -189,15 +189,22 @@ impl<T: Read+Seek> FatFileSystem<T> {
Ok(boot) Ok(boot)
} }
pub fn seek_to_sector(&mut self, sector: u64) -> io::Result<()> { // pub(crate) fn offset_from_cluster(&self, cluser: u32) -> u64 {
self.rdr.seek(SeekFrom::Start(sector*512))?; // self.offset_from_sector(self.sector_from_cluster(cluser))
Ok(()) // }
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 ((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 { pub(crate) fn get_root_dir_sector(&self) -> u32 {
match self.fat_type { match self.fat_type {
FatType::Fat12 | FatType::Fat16 => self.first_data_sector - self.root_dir_sectors, FatType::Fat12 | FatType::Fat16 => self.first_data_sector - self.root_dir_sectors,