Skip to content

Commit

Permalink
Fix skipping of extra LZW data
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski committed Jan 22, 2024
1 parent 27ea2f4 commit e91de3d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/reader/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ impl StreamingDecoder {
if left > 0 {
let n = cmp::min(left, buf.len());
if self.lzw_reader.has_ended() || matches!(write_into, OutputBuffer::None) {
return goto!(n, DecodeSubBlock(0), emit Decoded::Nothing);
return goto!(n, DecodeSubBlock(left - n), emit Decoded::Nothing);
}

let (mut consumed, bytes_len) = self.lzw_reader.decode_bytes(&buf[..n], write_into)?;
Expand Down
37 changes: 36 additions & 1 deletion tests/stall.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(feature = "std")]

use std::{fs, sync::mpsc, thread, time::Duration};
use std::{fs, sync::mpsc, thread, time::Duration, io};

#[test]
fn try_decode_crash_regression() {
Expand Down Expand Up @@ -42,3 +42,38 @@ fn decode(data: &[u8]) -> Result<(), gif::DecodingError> {

Ok(())
}

#[test]
fn one_byte_at_a_time() {
let r = OneByte {
data: include_bytes!("../tests/samples/moon_impact.gif"),
};
let frames = gif::DecodeOptions::new().read_info(r).unwrap()
.into_iter().enumerate().map(|(n, f)| {
f.expect(&n.to_string())
}).count();
assert_eq!(frames, 14);
}

struct OneByte<'a> {
data: &'a [u8],
}

impl io::BufRead for OneByte<'_> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Ok(&self.data[..self.data.len().min(1)])
}
fn consume(&mut self, n: usize) {
debug_assert!(n <= 1);
self.data = &self.data[n..];
}
}

impl io::Read for OneByte<'_> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = self.data.len().min(buf.len()).min(1);
buf[..n].copy_from_slice(&self.data[..n]);
self.data = &self.data[n..];
Ok(n)
}
}

0 comments on commit e91de3d

Please sign in to comment.