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),
#[error("referenced data to {data} is out of bounds at {offset}")]
OutOfBounds { data: &'static str, offset: usize },
#[error("Trying to read past the end of the file")]
Eof(usize),
}
#[derive(Debug, Error)]

View file

@ -128,7 +128,9 @@ trait Readable: Sized {
impl<T: Pod> Readable for T {
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))
}
}

View file

@ -188,11 +188,11 @@ bitflags! {
impl StripHeader {
/// Index into the VVD file vertexes
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> {
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)]

View file

@ -16,7 +16,13 @@ pub struct Vvd {
impl Vvd {
pub fn read(data: &[u8]) -> Result<Self> {
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() {
source_vertices
} else {
@ -24,10 +30,14 @@ impl Vvd {
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
{
let fixup = fixup?;
vertices.extend_from_slice(
&source_vertices[fixup.source_vertex_id as usize
..(fixup.source_vertex_id + fixup.vertex_count) as usize],
);
let from = fixup.source_vertex_id as usize;
let to = (fixup.source_vertex_id.saturating_add(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
};