Handle files with invalid filters

This commit is contained in:
Kornel 2021-06-15 13:04:15 +01:00
parent 286aaffa31
commit 31c5cf248a
2 changed files with 9 additions and 6 deletions

View file

@ -1,3 +1,5 @@
use crate::error::PngError;
pub fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8], buf: &mut Vec<u8>) {
assert!(data.len() >= bpp);
assert!(last_line.is_empty() || data.len() == last_line.len());
@ -65,7 +67,7 @@ pub fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8], buf: &
}
}
pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8], buf: &mut Vec<u8>) {
pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8], buf: &mut Vec<u8>) -> Result<(), PngError> {
buf.clear();
buf.reserve(data.len());
assert!(data.len() >= bpp);
@ -114,8 +116,9 @@ pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8], buf:
);
}
}
_ => unreachable!(),
_ => return Err(PngError::InvalidData),
}
Ok(())
}
fn paeth_predictor(a: u8, b: u8, c: u8) -> u8 {

View file

@ -136,7 +136,7 @@ impl PngData {
transparency_pixel,
aux_headers,
};
raw.data = raw.unfilter_image();
raw.data = raw.unfilter_image()?;
// Return the PngData
Ok(Self {
idat_data: idat_headers,
@ -281,7 +281,7 @@ impl PngImage {
}
/// Reverse all filters applied on the image, returning an unfiltered IDAT bytestream
fn unfilter_image(&self) -> Vec<u8> {
fn unfilter_image(&self) -> Result<Vec<u8>, PngError> {
let mut unfiltered = Vec::with_capacity(self.data.len());
let bpp = ((self.ihdr.bit_depth.as_u8() * self.channels_per_pixel() + 7) / 8) as usize;
let mut last_line: Vec<u8> = Vec::new();
@ -293,13 +293,13 @@ impl PngImage {
last_pass = line.pass;
}
last_line.resize(line.data.len(), 0);
unfilter_line(line.filter, bpp, line.data, &last_line, &mut unfiltered_buf);
unfilter_line(line.filter, bpp, line.data, &last_line, &mut unfiltered_buf)?;
unfiltered.push(0);
unfiltered.extend_from_slice(&unfiltered_buf);
std::mem::swap(&mut last_line, &mut unfiltered_buf);
unfiltered_buf.clear();
}
unfiltered
Ok(unfiltered)
}
/// Apply the specified filter type to all rows in the image