Skip to content

Commit

Permalink
Don't overflow if required buffer size exceeds usize::MAX (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
fintelia authored Oct 30, 2023
1 parent 22c994e commit e166779
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,15 +503,18 @@ impl<R: Read + Seek> WebPDecoder<R> {
self.read_chunk(WebPRiffChunk::XMP, self.memory_limit)
}

/// Returns the number of bytes required to store the image or a single frame.
pub fn output_buffer_size(&self) -> usize {
/// Returns the number of bytes required to store the image or a single frame, or None if that
/// would take more than usize::MAX bytes.
pub fn output_buffer_size(&self) -> Option<usize> {
let bytes_per_pixel = if self.has_alpha() { 4 } else { 3 };
self.width as usize * self.height as usize * bytes_per_pixel
(self.width as usize)
.checked_mul(self.height as usize)?
.checked_mul(bytes_per_pixel)
}

/// Returns the raw bytes of the image. For animated images, this is the first frame.
pub fn read_image(&mut self, buf: &mut [u8]) -> Result<(), DecodingError> {
assert_eq!(buf.len(), self.output_buffer_size());
assert_eq!(Some(buf.len()), self.output_buffer_size());

if let Some(range) = self.chunks.get(&WebPRiffChunk::VP8L) {
let mut frame = LosslessDecoder::new(range_reader(&mut self.r, range.clone())?);
Expand Down Expand Up @@ -582,6 +585,7 @@ impl<R: Read + Seek> WebPDecoder<R> {
/// Panics if the image is not animated.
pub fn read_frame(&mut self, buf: &mut [u8]) -> Result<Option<u32>, DecodingError> {
assert!(self.has_animation());
assert_eq!(Some(buf.len()), self.output_buffer_size());

if self.animation.loops_before_done == Some(0) {
return Ok(None);
Expand Down

0 comments on commit e166779

Please sign in to comment.