mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 16:44:11 +02:00
improve handling of mallformed inputs
This commit is contained in:
parent
7535da3250
commit
30e1ac4795
4 changed files with 22 additions and 8 deletions
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue