1
0
Fork 0
mirror of https://codeberg.org/icewind/vbsp.git synced 2026-06-03 10:44:07 +02:00

dont panic when parsing invalid displacement neighbours

This commit is contained in:
Robin Appelman 2022-12-23 14:34:33 +01:00
commit f22ee95214
5 changed files with 39 additions and 18 deletions

View file

@ -1,4 +1,5 @@
use super::vector::Vector;
use crate::error::InvalidNeighbourError;
use binrw::{BinRead, BinResult, ReadOptions};
use bitflags::bitflags;
use num_enum::TryFromPrimitive;
@ -75,7 +76,6 @@ impl BinRead for DisplacementNeighbour {
static_assertions::const_assert_eq!(size_of::<DisplacementNeighbour>(), 12);
#[derive(Debug, Clone, BinRead)]
#[br(assert(neighbour_index == u16::MAX || (neighbour_orientation < 4 && span < 4 && neighbour_span < 4), "valid neighbour index with invalid enum fields"))]
struct RawDisplacementSubNeighbour {
neighbour_index: u16,
neighbour_orientation: u8,
@ -101,18 +101,24 @@ pub struct DisplacementSubNeighbour {
}
impl TryFrom<RawDisplacementSubNeighbour> for DisplacementSubNeighbour {
type Error = ();
type Error = InvalidNeighbourError;
fn try_from(value: RawDisplacementSubNeighbour) -> Result<Self, Self::Error> {
match value.neighbour_index {
u16::MAX => Err(()),
u16::MAX => Err(InvalidNeighbourError::InvalidNeighbourIndex),
neighbour_index => Ok(DisplacementSubNeighbour {
neighbour_index,
// note that we already checked if these enums are valid in the assert of the RawDisplacementSubNeighbour reader
neighbour_orientation: NeighbourOrientation::try_from(value.neighbour_orientation)
.unwrap(),
span: NeighbourSpan::try_from(value.span).unwrap(),
neighbour_span: NeighbourSpan::try_from(value.neighbour_span).unwrap(),
.map_err(|_| {
InvalidNeighbourError::InvalidNeighbourOrientation(
value.neighbour_orientation,
)
})?,
span: NeighbourSpan::try_from(value.span)
.map_err(|_| InvalidNeighbourError::InvalidNeighbourSpan(value.span))?,
neighbour_span: NeighbourSpan::try_from(value.neighbour_span).map_err(|_| {
InvalidNeighbourError::InvalidNeighbourSpan(value.neighbour_span)
})?,
}),
}
}

View file

@ -32,7 +32,6 @@ where
{
use binrw::BinReaderExt;
use std::any::type_name;
use std::io::Cursor;
let bytes = [0; 512];
let mut reader = Cursor::new(bytes);

View file

@ -1,8 +1,8 @@
use crate::bspfile::LumpType;
use crate::data::*;
use std::num::{ParseFloatError, ParseIntError};
use thiserror::Error;
use zip::result::ZipError;
use crate::bspfile::LumpType;
#[non_exhaustive]
#[derive(Debug, Error)]
@ -105,6 +105,18 @@ pub enum ValidationError {
NonSquareDisplacement(i16),
#[error("No static prop lump found")]
NoStaticPropLump,
#[error(transparent)]
Neighbour(InvalidNeighbourError),
}
#[derive(Debug, Error)]
pub enum InvalidNeighbourError {
#[error("Invalid neighbour span")]
InvalidNeighbourIndex,
#[error("Invalid neighbour span")]
InvalidNeighbourSpan(u8),
#[error("Invalid neighbour orientation")]
InvalidNeighbourOrientation(u8),
}
#[derive(Debug, Error)]

View file

@ -122,7 +122,10 @@ impl<'a> Handle<'a, Leaf> {
impl<'a> Handle<'a, TextureInfo> {
pub fn texture_data(&self) -> Handle<'a, TextureData> {
Handle::new(self.bsp, &self.bsp.textures_data[self.data.texture_data_index as usize])
Handle::new(
self.bsp,
&self.bsp.textures_data[self.data.texture_data_index as usize],
)
}
pub fn name(&self) -> &'a str {
self.texture_data().name()
@ -139,4 +142,4 @@ impl<'a> Handle<'a, TextureData> {
part
}
}
}
}

View file

@ -16,8 +16,8 @@ use bspfile::BspFile;
pub use error::{BspError, StringError};
use lzma_rs::decompress::{Options, UnpackedSize};
use reader::LumpReader;
use std::{io::Read, ops::Deref};
use std::cmp::min;
use std::{io::Read, ops::Deref};
pub type BspResult<T> = Result<T, BspError>;
@ -197,9 +197,12 @@ impl Bsp {
let texture_string_tables = bsp_file
.lump_reader(LumpType::TextureDataStringTable)?
.read_vec(|r| r.read())?;
let texture_string_data = String::from_utf8(bsp_file
.get_lump(LumpType::TextureDataStringData)?
.into_owned()).map_err(|e| BspError::String(StringError::NonUTF8(e.utf8_error())))?;
let texture_string_data = String::from_utf8(
bsp_file
.get_lump(LumpType::TextureDataStringData)?
.into_owned(),
)
.map_err(|e| BspError::String(StringError::NonUTF8(e.utf8_error())))?;
let planes = bsp_file
.lump_reader(LumpType::Planes)?
.read_vec(|r| r.read())?;
@ -449,9 +452,7 @@ impl Bsp {
"texture_string_tables",
)?;
self.validate_indexes(
self.texture_string_tables
.iter()
.map(|texture| *texture),
self.texture_string_tables.iter().map(|texture| *texture),
&self.texture_string_data.as_bytes(),
"texture_string_tables",
"texture_string_data",