Skip to content

Commit 630e4c8

Browse files
author
HeroicKatora
authored
Merge pull request #203 from vstroebel/limits
Add limit for maximum output image
2 parents 31bd35c + c09d79b commit 630e4c8

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

src/decoder.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ pub struct Decoder<R> {
9696
coefficients: Vec<Vec<i16>>,
9797
// Bitmask of which coefficients has been completely decoded.
9898
coefficients_finished: [u64; MAX_COMPONENTS],
99+
100+
// Maximum allowed size of decoded image buffer
101+
decoding_buffer_size_limit: usize,
99102
}
100103

101104
impl<R: Read> Decoder<R> {
@@ -115,9 +118,15 @@ impl<R: Read> Decoder<R> {
115118
exif_data: None,
116119
coefficients: Vec::new(),
117120
coefficients_finished: [0; MAX_COMPONENTS],
121+
decoding_buffer_size_limit: usize::MAX,
118122
}
119123
}
120124

125+
/// Set maximum buffer size allowed for decoded images
126+
pub fn set_max_decoding_buffer_size(&mut self, max: usize) {
127+
self.decoding_buffer_size_limit = max;
128+
}
129+
121130
/// Returns metadata about the image.
122131
///
123132
/// The returned value will be `None` until a call to either `read_info` or `decode` has
@@ -532,6 +541,15 @@ impl<R: Read> Decoder<R> {
532541

533542
let frame = self.frame.as_ref().unwrap();
534543

544+
if {
545+
let required_mem = frame.components.len()
546+
.checked_mul(frame.output_size.width.into())
547+
.and_then(|m| m.checked_mul(frame.output_size.height.into()));
548+
required_mem.map_or(true, |m| self.decoding_buffer_size_limit < m)
549+
} {
550+
return Err(Error::Format("size of decoded image exceeds maximum allowed size".to_owned()));
551+
}
552+
535553
// If we're decoding a progressive jpeg and a component is unfinished, render what we've got
536554
if frame.coding_process == CodingProcess::DctProgressive
537555
&& self.coefficients.len() == frame.components.len()

0 commit comments

Comments
 (0)