Skip to content

Commit

Permalink
Merge pull request #1036 from fintelia/delay-overflow
Browse files Browse the repository at this point in the history
Fix potential overflow in GIF decoding
  • Loading branch information
fintelia authored Dec 20, 2019
2 parents 77bc941 + 38232ee commit 182de11
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
14 changes: 7 additions & 7 deletions src/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ impl<'a> Iterator for Frames<'a> {
/// A single animation frame
#[derive(Clone)]
pub struct Frame {
/// Delay between the frames in s
delay: Ratio<u16>,
/// Delay between the frames in milliseconds
delay_ms: Ratio<u32>,
/// x offset
left: u32,
/// y offset
Expand All @@ -49,26 +49,26 @@ impl Frame {
/// Contructs a new frame
pub fn new(buffer: RgbaImage) -> Frame {
Frame {
delay: Ratio::from_integer(0),
delay_ms: Ratio::from_integer(0),
left: 0,
top: 0,
buffer,
}
}

/// Contructs a new frame
pub fn from_parts(buffer: RgbaImage, left: u32, top: u32, delay: Ratio<u16>) -> Frame {
pub fn from_parts(buffer: RgbaImage, left: u32, top: u32, delay_ms: Ratio<u32>) -> Frame {
Frame {
delay,
delay_ms,
left,
top,
buffer,
}
}

/// Delay of this frame
pub fn delay(&self) -> Ratio<u16> {
self.delay
pub fn delay_ms(&self) -> Ratio<u32> {
self.delay_ms
}

/// Returns the image buffer
Expand Down
7 changes: 4 additions & 3 deletions src/gif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern crate gif;
extern crate num_rational;

use std::clone::Clone;
use std::convert::TryInto;
use std::cmp::min;
use std::convert::TryFrom;
use std::io::{self, Cursor, Read, Write};
Expand Down Expand Up @@ -190,7 +191,7 @@ impl<R: Read> Iterator for GifFrameIterator<R> {
f_height = u32::from(frame.height);

// frame.delay is in units of 10ms so frame.delay*10 is in ms
delay = Ratio::new(frame.delay * 10, 1);
delay = Ratio::new(u32::from(frame.delay) * 10, 1);
dispose = frame.dispose;
} else {
// no more frames
Expand Down Expand Up @@ -363,13 +364,13 @@ impl<W: Write> Encoder<W> {

fn encode_single_frame(&mut self, img_frame: animation::Frame) -> ImageResult<()> {
// get the delay before converting img_frame
let frame_delay = img_frame.delay().to_integer();
let frame_delay = img_frame.delay_ms().to_integer();
// convert img_frame into RgbaImage
let rbga_frame = img_frame.into_buffer();

// Create the gif::Frame from the animation::Frame
let mut frame = Frame::from_rgba(rbga_frame.width() as u16, rbga_frame.height() as u16, &mut rbga_frame.into_raw());
frame.delay = frame_delay;
frame.delay = (frame_delay / 10).try_into().map_err(|_|ImageError::DimensionError)?;

// encode the gif::Frame
self.encode(&frame)
Expand Down

0 comments on commit 182de11

Please sign in to comment.