improve handling of mallformed inputs

This commit is contained in:
Robin Appelman 2022-12-24 19:44:39 +01:00
commit 30e1ac4795
4 changed files with 22 additions and 8 deletions

View file

@ -9,6 +9,8 @@ pub enum ModelError {
String(#[from] StringError), String(#[from] StringError),
#[error("referenced data to {data} is out of bounds at {offset}")] #[error("referenced data to {data} is out of bounds at {offset}")]
OutOfBounds { data: &'static str, offset: usize }, OutOfBounds { data: &'static str, offset: usize },
#[error("Trying to read past the end of the file")]
Eof(usize),
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]

View file

@ -128,7 +128,9 @@ trait Readable: Sized {
impl<T: Pod> Readable for T { impl<T: Pod> Readable for T {
fn read(data: &[u8]) -> Result<Self, ModelError> { fn read(data: &[u8]) -> Result<Self, ModelError> {
let data = &data[0..size_of::<Self>()]; let data = data
.get(0..size_of::<Self>())
.ok_or(ModelError::Eof(size_of::<Self>()))?;
Ok(pod_read_unaligned(data)) Ok(pod_read_unaligned(data))
} }
} }

View file

@ -188,11 +188,11 @@ bitflags! {
impl StripHeader { impl StripHeader {
/// Index into the VVD file vertexes /// Index into the VVD file vertexes
pub fn vertex_indexes(&self) -> Range<usize> { pub fn vertex_indexes(&self) -> Range<usize> {
self.vertex_offset as usize..(self.vertex_offset + self.vertex_count) as usize self.vertex_offset as usize..(self.vertex_offset.saturating_add(self.vertex_count)) as usize
} }
pub fn index_indexes(&self) -> Range<usize> { pub fn index_indexes(&self) -> Range<usize> {
self.index_offset as usize..(self.index_offset + self.index_count) as usize self.index_offset as usize..(self.index_offset.saturating_add(self.index_count)) as usize
} }
#[allow(dead_code)] #[allow(dead_code)]

View file

@ -16,7 +16,13 @@ pub struct Vvd {
impl Vvd { impl Vvd {
pub fn read(data: &[u8]) -> Result<Self> { pub fn read(data: &[u8]) -> Result<Self> {
let header = <VvdHeader as Readable>::read(data)?; let header = <VvdHeader as Readable>::read(data)?;
let source_vertices = read_relative(data, header.vertex_indexes(0).unwrap())?; let source_vertices = read_relative(
data,
header.vertex_indexes(0).ok_or(ModelError::OutOfBounds {
data: "model_lod",
offset: 0,
})?,
)?;
let vertices = if !header.has_fixups() { let vertices = if !header.has_fixups() {
source_vertices source_vertices
} else { } else {
@ -24,10 +30,14 @@ impl Vvd {
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes()) for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
{ {
let fixup = fixup?; let fixup = fixup?;
vertices.extend_from_slice( let from = fixup.source_vertex_id as usize;
&source_vertices[fixup.source_vertex_id as usize let to = (fixup.source_vertex_id.saturating_add(fixup.vertex_count)) as usize;
..(fixup.source_vertex_id + fixup.vertex_count) as usize], vertices.extend_from_slice(&source_vertices.get(from..to).ok_or_else(|| {
); ModelError::OutOfBounds {
data: "source_vertices",
offset: to as usize,
}
})?);
} }
vertices vertices
}; };