Tidy up errors

This commit is contained in:
Andrew 2025-08-04 18:16:03 +12:00
parent be608ea876
commit c4342cb073
5 changed files with 35 additions and 34 deletions

View file

@ -116,7 +116,7 @@ impl TryFrom<u8> for BitDepth {
4 => Ok(Self::Four),
8 => Ok(Self::Eight),
16 => Ok(Self::Sixteen),
_ => Err(PngError::new("Unexpected bit depth")),
_ => Err(PngError::InvalidData),
}
}
}

View file

@ -22,7 +22,7 @@ pub fn inflate(data: &[u8], out_size: usize) -> PngResult<Vec<u8>> {
.zlib_decompress(data, &mut dest)
.map_err(|err| match err {
DecompressionError::BadData => PngError::InvalidData,
DecompressionError::InsufficientSpace => PngError::new("inflated data too long"),
DecompressionError::InsufficientSpace => PngError::InflatedDataTooLong(out_size),
})?;
dest.truncate(len);
Ok(dest)

View file

@ -5,17 +5,17 @@ use crate::colors::{BitDepth, ColorType};
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum PngError {
DeflatedDataTooLong(usize),
TimedOut,
NotPNG,
APNGNotSupported,
APNGOutOfOrder,
InvalidData,
TruncatedData,
ChunkMissing(&'static str),
InvalidDepthForType(BitDepth, ColorType),
IncorrectDataLength(usize, usize),
C2PAMetadataPreventsChanges,
ChunkMissing(&'static str),
CRCMismatch([u8; 4]),
DeflatedDataTooLong(usize),
IncorrectDataLength(usize, usize),
InflatedDataTooLong(usize),
InvalidData,
InvalidDepthForType(BitDepth, ColorType),
NotPNG,
TruncatedData,
Other(Box<str>),
}
@ -26,26 +26,30 @@ impl fmt::Display for PngError {
#[cold]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
PngError::DeflatedDataTooLong(_) => f.write_str("deflated data too long"),
PngError::TimedOut => f.write_str("timed out"),
PngError::NotPNG => f.write_str("Invalid header detected; Not a PNG file"),
PngError::InvalidData => f.write_str("Invalid data found; unable to read PNG file"),
PngError::TruncatedData => {
f.write_str("Missing data in the file; the file is truncated")
}
PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"),
PngError::APNGOutOfOrder => f.write_str("APNG chunks are out of order"),
PngError::C2PAMetadataPreventsChanges => f.write_str(
"The image contains C2PA manifest that would be invalidated by any file changes",
),
PngError::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"),
PngError::InvalidDepthForType(d, ref c) => {
write!(f, "Invalid bit depth {d} for color type {c}")
}
PngError::CRCMismatch(ref c) => write!(
f,
"CRC mismatch in {} chunk; May be recoverable by using --fix",
String::from_utf8_lossy(c)
),
PngError::DeflatedDataTooLong(_) => f.write_str("Deflated data too long"),
PngError::IncorrectDataLength(l1, l2) => write!(
f,
"Data length {l1} does not match the expected length {l2}"
),
PngError::C2PAMetadataPreventsChanges => f.write_str(
"The image contains C2PA manifest that would be invalidated by any file changes",
),
PngError::InflatedDataTooLong(_) => f.write_str("Inflated data too long"),
PngError::InvalidData => f.write_str("Invalid data found; unable to read PNG file"),
PngError::InvalidDepthForType(d, ref c) => {
write!(f, "Invalid bit depth {d} for color type {c}")
}
PngError::NotPNG => f.write_str("Invalid header detected; Not a PNG file"),
PngError::TruncatedData => {
f.write_str("Missing data in the file; the file is truncated")
}
PngError::Other(ref s) => f.write_str(s),
}
}

View file

@ -172,10 +172,7 @@ pub fn parse_next_chunk<'a>(
let chunk_bytes = &byte_data[chunk_start..chunk_start + 4 + length as usize];
if !fix_errors && crc32(chunk_bytes) != crc {
return Err(PngError::new(&format!(
"CRC Mismatch in {} chunk; May be recoverable by using --fix",
String::from_utf8_lossy(chunk_name)
)));
return Err(PngError::CRCMismatch(chunk_name.try_into().unwrap()));
}
let name: [u8; 4] = chunk_name.try_into().unwrap();
@ -208,7 +205,7 @@ pub fn parse_ihdr_chunk(
},
4 => ColorType::GrayscaleAlpha,
6 => ColorType::RGBA,
_ => return Err(PngError::new("Unexpected color type in header")),
_ => return Err(PngError::InvalidData),
},
bit_depth: byte_data[8].try_into()?,
width: read_be_u32(&byte_data[0..4]),
@ -216,7 +213,7 @@ pub fn parse_ihdr_chunk(
interlaced: match interlaced {
0 => false,
1 => true,
_ => return Err(PngError::new("Unexpected interlacing in header")),
_ => return Err(PngError::InvalidData),
},
})
}
@ -226,7 +223,7 @@ fn palette_to_rgba(
palette_data: Option<Vec<u8>>,
trns_data: Option<Vec<u8>>,
) -> Result<Vec<RGBA8>, PngError> {
let palette_data = palette_data.ok_or_else(|| PngError::new("no palette in indexed image"))?;
let palette_data = palette_data.ok_or(PngError::ChunkMissing("PLTE"))?;
let mut palette: Vec<_> = palette_data
.chunks_exact(3)
.map(|color| RGBA8::new(color[0], color[1], color[2], 255))

View file

@ -679,7 +679,7 @@ fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()>
.set_permissions(metadata_input.permissions())
.map_err(|err_io| {
PngError::new(&format!(
"unable to set permissions for output file: {err_io}"
"Unable to set permissions for output file: {err_io}"
))
})
}
@ -695,7 +695,7 @@ fn copy_times(input_path_meta: &Metadata, out_path: &Path) -> PngResult<()> {
trace!("attempting to set file modification time: {mtime:?}");
filetime::set_file_mtime(out_path, mtime).map_err(|err_io| {
PngError::new(&format!(
"unable to set file times on {out_path:?}: {err_io}"
"Unable to set file times on {out_path:?}: {err_io}"
))
})
}