Validation checks for RawImage construction

This commit is contained in:
Andrew 2022-12-19 19:36:11 +13:00
parent 9dfd1b867c
commit 16842eb33d
2 changed files with 29 additions and 0 deletions

View file

@ -1,3 +1,4 @@
use crate::colors::{BitDepth, ColorType};
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
@ -11,6 +12,8 @@ pub enum PngError {
InvalidData, InvalidData,
TruncatedData, TruncatedData,
ChunkMissing(&'static str), ChunkMissing(&'static str),
InvalidDepthForType(BitDepth, ColorType),
IncorrectDataLength(usize, usize),
Other(Box<str>), Other(Box<str>),
} }
@ -30,6 +33,14 @@ impl fmt::Display for PngError {
} }
PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"), PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"),
PngError::ChunkMissing(s) => write!(f, "Chunk {} missing or empty", s), PngError::ChunkMissing(s) => write!(f, "Chunk {} missing or empty", s),
PngError::InvalidDepthForType(d, ref c) => {
write!(f, "Invalid bit depth {} for color type {}", d, c)
}
PngError::IncorrectDataLength(l1, l2) => write!(
f,
"Data length {} does not match the expected length {}",
l1, l2
),
PngError::Other(ref s) => f.write_str(s), PngError::Other(ref s) => f.write_str(s),
} }
} }

View file

@ -331,6 +331,24 @@ impl RawImage {
bit_depth: BitDepth, bit_depth: BitDepth,
data: Vec<u8>, data: Vec<u8>,
) -> Result<Self, PngError> { ) -> Result<Self, PngError> {
// Validate bit depth
let valid_depth = match color_type {
ColorType::Grayscale { .. } => true,
ColorType::Indexed { .. } => (bit_depth as u8) <= 8,
_ => (bit_depth as u8) >= 8,
};
if !valid_depth {
return Err(PngError::InvalidDepthForType(bit_depth, color_type));
}
// Validate data length
let bpp = bit_depth as usize * color_type.channels_per_pixel() as usize;
let row_bytes = (bpp * width as usize + 7) / 8;
let expected_len = row_bytes * height as usize;
if data.len() != expected_len {
return Err(PngError::IncorrectDataLength(data.len(), expected_len));
}
Ok(Self { Ok(Self {
png: Arc::new(PngImage { png: Arc::new(PngImage {
ihdr: IhdrData { ihdr: IhdrData {