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:
parent
148c6c59bd
commit
f22ee95214
5 changed files with 39 additions and 18 deletions
|
|
@ -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)
|
||||
})?,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
14
src/error.rs
14
src/error.rs
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
src/lib.rs
15
src/lib.rs
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue