Tidy up errors
This commit is contained in:
parent
be608ea876
commit
c4342cb073
5 changed files with 35 additions and 34 deletions
|
|
@ -116,7 +116,7 @@ impl TryFrom<u8> for BitDepth {
|
||||||
4 => Ok(Self::Four),
|
4 => Ok(Self::Four),
|
||||||
8 => Ok(Self::Eight),
|
8 => Ok(Self::Eight),
|
||||||
16 => Ok(Self::Sixteen),
|
16 => Ok(Self::Sixteen),
|
||||||
_ => Err(PngError::new("Unexpected bit depth")),
|
_ => Err(PngError::InvalidData),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub fn inflate(data: &[u8], out_size: usize) -> PngResult<Vec<u8>> {
|
||||||
.zlib_decompress(data, &mut dest)
|
.zlib_decompress(data, &mut dest)
|
||||||
.map_err(|err| match err {
|
.map_err(|err| match err {
|
||||||
DecompressionError::BadData => PngError::InvalidData,
|
DecompressionError::BadData => PngError::InvalidData,
|
||||||
DecompressionError::InsufficientSpace => PngError::new("inflated data too long"),
|
DecompressionError::InsufficientSpace => PngError::InflatedDataTooLong(out_size),
|
||||||
})?;
|
})?;
|
||||||
dest.truncate(len);
|
dest.truncate(len);
|
||||||
Ok(dest)
|
Ok(dest)
|
||||||
|
|
|
||||||
50
src/error.rs
50
src/error.rs
|
|
@ -5,17 +5,17 @@ use crate::colors::{BitDepth, ColorType};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum PngError {
|
pub enum PngError {
|
||||||
DeflatedDataTooLong(usize),
|
|
||||||
TimedOut,
|
|
||||||
NotPNG,
|
|
||||||
APNGNotSupported,
|
|
||||||
APNGOutOfOrder,
|
APNGOutOfOrder,
|
||||||
InvalidData,
|
|
||||||
TruncatedData,
|
|
||||||
ChunkMissing(&'static str),
|
|
||||||
InvalidDepthForType(BitDepth, ColorType),
|
|
||||||
IncorrectDataLength(usize, usize),
|
|
||||||
C2PAMetadataPreventsChanges,
|
C2PAMetadataPreventsChanges,
|
||||||
|
ChunkMissing(&'static str),
|
||||||
|
CRCMismatch([u8; 4]),
|
||||||
|
DeflatedDataTooLong(usize),
|
||||||
|
IncorrectDataLength(usize, usize),
|
||||||
|
InflatedDataTooLong(usize),
|
||||||
|
InvalidData,
|
||||||
|
InvalidDepthForType(BitDepth, ColorType),
|
||||||
|
NotPNG,
|
||||||
|
TruncatedData,
|
||||||
Other(Box<str>),
|
Other(Box<str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,26 +26,30 @@ impl fmt::Display for PngError {
|
||||||
#[cold]
|
#[cold]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
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::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::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"),
|
||||||
PngError::InvalidDepthForType(d, ref c) => {
|
PngError::CRCMismatch(ref c) => write!(
|
||||||
write!(f, "Invalid bit depth {d} for color type {c}")
|
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!(
|
PngError::IncorrectDataLength(l1, l2) => write!(
|
||||||
f,
|
f,
|
||||||
"Data length {l1} does not match the expected length {l2}"
|
"Data length {l1} does not match the expected length {l2}"
|
||||||
),
|
),
|
||||||
PngError::C2PAMetadataPreventsChanges => f.write_str(
|
PngError::InflatedDataTooLong(_) => f.write_str("Inflated data too long"),
|
||||||
"The image contains C2PA manifest that would be invalidated by any file changes",
|
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),
|
PngError::Other(ref s) => f.write_str(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,10 +172,7 @@ pub fn parse_next_chunk<'a>(
|
||||||
|
|
||||||
let chunk_bytes = &byte_data[chunk_start..chunk_start + 4 + length as usize];
|
let chunk_bytes = &byte_data[chunk_start..chunk_start + 4 + length as usize];
|
||||||
if !fix_errors && crc32(chunk_bytes) != crc {
|
if !fix_errors && crc32(chunk_bytes) != crc {
|
||||||
return Err(PngError::new(&format!(
|
return Err(PngError::CRCMismatch(chunk_name.try_into().unwrap()));
|
||||||
"CRC Mismatch in {} chunk; May be recoverable by using --fix",
|
|
||||||
String::from_utf8_lossy(chunk_name)
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let name: [u8; 4] = 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,
|
4 => ColorType::GrayscaleAlpha,
|
||||||
6 => ColorType::RGBA,
|
6 => ColorType::RGBA,
|
||||||
_ => return Err(PngError::new("Unexpected color type in header")),
|
_ => return Err(PngError::InvalidData),
|
||||||
},
|
},
|
||||||
bit_depth: byte_data[8].try_into()?,
|
bit_depth: byte_data[8].try_into()?,
|
||||||
width: read_be_u32(&byte_data[0..4]),
|
width: read_be_u32(&byte_data[0..4]),
|
||||||
|
|
@ -216,7 +213,7 @@ pub fn parse_ihdr_chunk(
|
||||||
interlaced: match interlaced {
|
interlaced: match interlaced {
|
||||||
0 => false,
|
0 => false,
|
||||||
1 => true,
|
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>>,
|
palette_data: Option<Vec<u8>>,
|
||||||
trns_data: Option<Vec<u8>>,
|
trns_data: Option<Vec<u8>>,
|
||||||
) -> Result<Vec<RGBA8>, PngError> {
|
) -> 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
|
let mut palette: Vec<_> = palette_data
|
||||||
.chunks_exact(3)
|
.chunks_exact(3)
|
||||||
.map(|color| RGBA8::new(color[0], color[1], color[2], 255))
|
.map(|color| RGBA8::new(color[0], color[1], color[2], 255))
|
||||||
|
|
|
||||||
|
|
@ -679,7 +679,7 @@ fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()>
|
||||||
.set_permissions(metadata_input.permissions())
|
.set_permissions(metadata_input.permissions())
|
||||||
.map_err(|err_io| {
|
.map_err(|err_io| {
|
||||||
PngError::new(&format!(
|
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:?}");
|
trace!("attempting to set file modification time: {mtime:?}");
|
||||||
filetime::set_file_mtime(out_path, mtime).map_err(|err_io| {
|
filetime::set_file_mtime(out_path, mtime).map_err(|err_io| {
|
||||||
PngError::new(&format!(
|
PngError::new(&format!(
|
||||||
"unable to set file times on {out_path:?}: {err_io}"
|
"Unable to set file times on {out_path:?}: {err_io}"
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue