mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 22:42:46 +00:00
Validate GIF frame length before copying
This commit is contained in:
1 parent
d5e9fd7a49
commit
543e5d4983
1 file changed
+12
-4
+12
-4
@@ -90,10 +90,7 @@ pub fn prepare_frame(width: u32, height: u32, mut pixels: Vec<u8>, speed: i32) -
|
||||
if !(1..=30).contains(&speed) {
|
||||
return Err(Error::InvalidSpeed(speed));
|
||||
}
|
||||
let expected = usize::from(width)
|
||||
.checked_mul(usize::from(height))
|
||||
.and_then(|pixels| pixels.checked_mul(4))
|
||||
.ok_or(Error::Dimensions { width: u32::from(width), height: u32::from(height) })?;
|
||||
let expected = rgba_len(width, height)?;
|
||||
if pixels.len() != expected {
|
||||
return Err(Error::FrameLength { index: 0, actual: pixels.len(), expected });
|
||||
}
|
||||
@@ -101,6 +98,13 @@ pub fn prepare_frame(width: u32, height: u32, mut pixels: Vec<u8>, speed: i32) -
|
||||
Ok(PreparedFrame { width, height, frame })
|
||||
}
|
||||
|
||||
fn rgba_len(width: u16, height: u16) -> Result<usize, Error> {
|
||||
usize::from(width)
|
||||
.checked_mul(usize::from(height))
|
||||
.and_then(|pixels| pixels.checked_mul(4))
|
||||
.ok_or(Error::Dimensions { width: u32::from(width), height: u32::from(height) })
|
||||
}
|
||||
|
||||
fn dimensions(width: u32, height: u32) -> Result<(u16, u16), Error> {
|
||||
if width == 0 || height == 0 || width > u32::from(u16::MAX) || height > u32::from(u16::MAX) {
|
||||
return Err(Error::Dimensions { width, height });
|
||||
@@ -135,6 +139,10 @@ impl<W: Write> AnimationWriter<W> {
|
||||
|
||||
/// Encode and append one full-canvas RGBA8 frame.
|
||||
pub fn write_frame(&mut self, frame: RgbaFrame<'_>) -> Result<(), Error> {
|
||||
let expected = rgba_len(self.width, self.height)?;
|
||||
if frame.pixels.len() != expected {
|
||||
return Err(Error::FrameLength { index: self.frames_written, actual: frame.pixels.len(), expected });
|
||||
}
|
||||
let prepared =
|
||||
prepare_frame(u32::from(self.width), u32::from(self.height), frame.pixels.to_vec(), self.options.speed).map_err(|error| match error {
|
||||
Error::FrameLength { actual, expected, .. } => Error::FrameLength { index: self.frames_written, actual, expected },
|
||||
|
||||
Reference in new issue
Block a user