From 0b5dc724549c48a9f59324dc2e22547e197f50d3 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Fri, 7 Nov 2025 22:09:41 +0100 Subject: [PATCH 1/2] Fix: uncompressed encoder doing short writes --- src/encoder/compression/uncompressed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encoder/compression/uncompressed.rs b/src/encoder/compression/uncompressed.rs index f414403..2385d9e 100644 --- a/src/encoder/compression/uncompressed.rs +++ b/src/encoder/compression/uncompressed.rs @@ -14,7 +14,7 @@ impl Compression for Uncompressed { impl CompressionAlgorithm for Uncompressed { fn write_to(&mut self, writer: &mut W, bytes: &[u8]) -> Result { - writer.write(bytes).map(|byte_count| byte_count as u64) + writer.write_all(bytes).map(|()| bytes.len() as u64) } } From 02118620e2a002992b77a3bcdb94cdf547b48b70 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Sat, 8 Nov 2025 11:16:09 +0100 Subject: [PATCH 2/2] Verify handling of a blocked writer --- src/encoder/writer.rs | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/encoder/writer.rs b/src/encoder/writer.rs index f45038b..e3585cc 100644 --- a/src/encoder/writer.rs +++ b/src/encoder/writer.rs @@ -190,3 +190,58 @@ impl TiffWriter { Ok(()) } } + +#[test] +fn encoder_on_short_writes() { + struct ShortWriter { + inner: T, + } + + impl std::io::Write for ShortWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + let lower_bound = buf.len().min(1); + let lower = buf.len().saturating_sub(1).max(lower_bound); + + self.inner.write(&buf[..lower]) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } + } + + impl std::io::Seek for ShortWriter { + fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { + self.inner.seek(pos) + } + } + + let mut write = ShortWriter { + inner: std::io::Cursor::new(vec![0u8; 0]), + }; + + let imgdata = vec![42u8; 100 * 100]; + for comp in [ + super::Compression::Uncompressed, + super::Compression::Packbits, + ] { + write.inner.set_position(0); + write.inner.get_mut().clear(); + + { + let mut tiff_writer = super::TiffEncoder::new(&mut write) + .unwrap() + .with_compression(comp); + + tiff_writer + .write_image::(100, 100, &imgdata) + .unwrap(); + } + + write.inner.set_position(0); + let mut tiff_reader = crate::decoder::Decoder::new(&mut write.inner).unwrap(); + let data = tiff_reader.read_image().unwrap(); + + assert!(matches!(data, crate::decoder::DecodingResult::U8(v) if v == imgdata)); + } +}