diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index c67df27..8c333ec 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -580,7 +580,7 @@ impl Decoder { (bytes, Box::new(reader)) } CompressionMethod::OldDeflate => { - let (bytes, reader) = DeflateReader::new(&mut self.reader)?; + let (bytes, reader) = DeflateReader::new(&mut self.reader, max_uncompressed_length)?; (bytes, Box::new(reader)) } method => { diff --git a/src/decoder/stream.rs b/src/decoder/stream.rs index 58a6350..fe5d20c 100644 --- a/src/decoder/stream.rs +++ b/src/decoder/stream.rs @@ -1,6 +1,6 @@ //! All IO functionality needed for TIFF decoding -use crate::error::TiffResult; +use crate::error::{TiffError, TiffResult}; use byteorder::{BigEndian, LittleEndian, ReadBytesExt}; use lzw; use miniz_oxide::inflate; @@ -76,11 +76,22 @@ pub struct DeflateReader { } impl DeflateReader { - pub fn new(reader: &mut SmartReader) -> TiffResult<(usize, Self)> { + pub fn new( + reader: &mut SmartReader, + max_uncompressed_length: usize, + ) -> TiffResult<(usize, Self)> { let byte_order = reader.byte_order; let mut compressed = Vec::new(); reader.read_to_end(&mut compressed)?; - let uncompressed = inflate::decompress_to_vec_zlib(&compressed)?; + + // TODO: Implement streaming compression, and remove this (temporary) and somewhat + // misleading workaround. + if compressed.len() > max_uncompressed_length { + return Err(TiffError::LimitsExceeded); + } + + let uncompressed = + inflate::decompress_to_vec_zlib(&compressed).map_err(TiffError::from_inflate_status)?; Ok(( uncompressed.len(), diff --git a/src/error.rs b/src/error.rs index cbe7e3f..6c6021b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -67,15 +67,15 @@ pub struct InflateError { status: TINFLStatus, } -impl From for TiffFormatError { - fn from(status: TINFLStatus) -> Self { - TiffFormatError::InflateError(InflateError { status }) +impl InflateError { + pub fn new(status: TINFLStatus) -> Self { + Self { status } } } -impl From for TiffError { - fn from(status: TINFLStatus) -> Self { - TiffError::FormatError(status.into()) +impl TiffError { + pub(crate) fn from_inflate_status(status: TINFLStatus) -> Self { + TiffError::FormatError(TiffFormatError::InflateError(InflateError::new(status))) } }