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 super::vector::Vector;
|
||||||
|
use crate::error::InvalidNeighbourError;
|
||||||
use binrw::{BinRead, BinResult, ReadOptions};
|
use binrw::{BinRead, BinResult, ReadOptions};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
|
|
@ -75,7 +76,6 @@ impl BinRead for DisplacementNeighbour {
|
||||||
static_assertions::const_assert_eq!(size_of::<DisplacementNeighbour>(), 12);
|
static_assertions::const_assert_eq!(size_of::<DisplacementNeighbour>(), 12);
|
||||||
|
|
||||||
#[derive(Debug, Clone, BinRead)]
|
#[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 {
|
struct RawDisplacementSubNeighbour {
|
||||||
neighbour_index: u16,
|
neighbour_index: u16,
|
||||||
neighbour_orientation: u8,
|
neighbour_orientation: u8,
|
||||||
|
|
@ -101,18 +101,24 @@ pub struct DisplacementSubNeighbour {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<RawDisplacementSubNeighbour> for DisplacementSubNeighbour {
|
impl TryFrom<RawDisplacementSubNeighbour> for DisplacementSubNeighbour {
|
||||||
type Error = ();
|
type Error = InvalidNeighbourError;
|
||||||
|
|
||||||
fn try_from(value: RawDisplacementSubNeighbour) -> Result<Self, Self::Error> {
|
fn try_from(value: RawDisplacementSubNeighbour) -> Result<Self, Self::Error> {
|
||||||
match value.neighbour_index {
|
match value.neighbour_index {
|
||||||
u16::MAX => Err(()),
|
u16::MAX => Err(InvalidNeighbourError::InvalidNeighbourIndex),
|
||||||
neighbour_index => Ok(DisplacementSubNeighbour {
|
neighbour_index => Ok(DisplacementSubNeighbour {
|
||||||
neighbour_index,
|
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)
|
neighbour_orientation: NeighbourOrientation::try_from(value.neighbour_orientation)
|
||||||
.unwrap(),
|
.map_err(|_| {
|
||||||
span: NeighbourSpan::try_from(value.span).unwrap(),
|
InvalidNeighbourError::InvalidNeighbourOrientation(
|
||||||
neighbour_span: NeighbourSpan::try_from(value.neighbour_span).unwrap(),
|
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 binrw::BinReaderExt;
|
||||||
use std::any::type_name;
|
use std::any::type_name;
|
||||||
use std::io::Cursor;
|
|
||||||
|
|
||||||
let bytes = [0; 512];
|
let bytes = [0; 512];
|
||||||
let mut reader = Cursor::new(bytes);
|
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 crate::data::*;
|
||||||
use std::num::{ParseFloatError, ParseIntError};
|
use std::num::{ParseFloatError, ParseIntError};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use zip::result::ZipError;
|
use zip::result::ZipError;
|
||||||
use crate::bspfile::LumpType;
|
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
@ -105,6 +105,18 @@ pub enum ValidationError {
|
||||||
NonSquareDisplacement(i16),
|
NonSquareDisplacement(i16),
|
||||||
#[error("No static prop lump found")]
|
#[error("No static prop lump found")]
|
||||||
NoStaticPropLump,
|
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)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,10 @@ impl<'a> Handle<'a, Leaf> {
|
||||||
|
|
||||||
impl<'a> Handle<'a, TextureInfo> {
|
impl<'a> Handle<'a, TextureInfo> {
|
||||||
pub fn texture_data(&self) -> Handle<'a, TextureData> {
|
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 {
|
pub fn name(&self) -> &'a str {
|
||||||
self.texture_data().name()
|
self.texture_data().name()
|
||||||
|
|
|
||||||
13
src/lib.rs
13
src/lib.rs
|
|
@ -16,8 +16,8 @@ use bspfile::BspFile;
|
||||||
pub use error::{BspError, StringError};
|
pub use error::{BspError, StringError};
|
||||||
use lzma_rs::decompress::{Options, UnpackedSize};
|
use lzma_rs::decompress::{Options, UnpackedSize};
|
||||||
use reader::LumpReader;
|
use reader::LumpReader;
|
||||||
use std::{io::Read, ops::Deref};
|
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
use std::{io::Read, ops::Deref};
|
||||||
|
|
||||||
pub type BspResult<T> = Result<T, BspError>;
|
pub type BspResult<T> = Result<T, BspError>;
|
||||||
|
|
||||||
|
|
@ -197,9 +197,12 @@ impl Bsp {
|
||||||
let texture_string_tables = bsp_file
|
let texture_string_tables = bsp_file
|
||||||
.lump_reader(LumpType::TextureDataStringTable)?
|
.lump_reader(LumpType::TextureDataStringTable)?
|
||||||
.read_vec(|r| r.read())?;
|
.read_vec(|r| r.read())?;
|
||||||
let texture_string_data = String::from_utf8(bsp_file
|
let texture_string_data = String::from_utf8(
|
||||||
|
bsp_file
|
||||||
.get_lump(LumpType::TextureDataStringData)?
|
.get_lump(LumpType::TextureDataStringData)?
|
||||||
.into_owned()).map_err(|e| BspError::String(StringError::NonUTF8(e.utf8_error())))?;
|
.into_owned(),
|
||||||
|
)
|
||||||
|
.map_err(|e| BspError::String(StringError::NonUTF8(e.utf8_error())))?;
|
||||||
let planes = bsp_file
|
let planes = bsp_file
|
||||||
.lump_reader(LumpType::Planes)?
|
.lump_reader(LumpType::Planes)?
|
||||||
.read_vec(|r| r.read())?;
|
.read_vec(|r| r.read())?;
|
||||||
|
|
@ -449,9 +452,7 @@ impl Bsp {
|
||||||
"texture_string_tables",
|
"texture_string_tables",
|
||||||
)?;
|
)?;
|
||||||
self.validate_indexes(
|
self.validate_indexes(
|
||||||
self.texture_string_tables
|
self.texture_string_tables.iter().map(|texture| *texture),
|
||||||
.iter()
|
|
||||||
.map(|texture| *texture),
|
|
||||||
&self.texture_string_data.as_bytes(),
|
&self.texture_string_data.as_bytes(),
|
||||||
"texture_string_tables",
|
"texture_string_tables",
|
||||||
"texture_string_data",
|
"texture_string_data",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue