image-png
image-png copied to clipboard
[bug] infinite loop in into_stream_writer_with_size
The following rust code:
let file = OpenOptions::new().write(true).create(true).open("/tmp/myimage.png").unwrap();
let encoder = png::Encoder::new(file, 2, 2);
encoder.write_header().unwrap().into_stream_writer_with_size(2);
never exits and creates the following never-ending file :
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 00 02 00 00 00 02 08 00 00 00 00 57 dd 52 |.............W.R|
00000020 f8 00 00 00 02 49 44 41 54 02 00 4e cd df 38 00 |.....IDAT..N..8.|
00000030 00 00 02 49 44 41 54 00 00 7c fb bd ba 00 00 00 |...IDAT..|......|
00000040 02 49 44 41 54 ff ff c2 dd af 45 00 00 00 02 49 |.IDAT.....E....I|
00000050 44 41 54 02 00 4e cd df 38 00 00 00 02 49 44 41 |DAT..N..8....IDA|
00000060 54 00 00 7c fb bd ba 00 00 00 02 49 44 41 54 ff |T..|.......IDAT.|
00000070 ff c2 dd af 45 00 00 00 02 49 44 41 54 02 00 4e |....E....IDAT..N|
00000080 cd df 38 00 00 00 02 49 44 41 54 00 00 7c fb bd |..8....IDAT..|..|
00000090 ba 00 00 00 02 49 44 41 54 ff ff c2 dd af 45 00 |.....IDAT.....E.|
000000a0 00 00 02 49 44 41 54 02 00 4e cd df 38 00 00 00 |...IDAT..N..8...|
000000b0 02 49 44 41 54 00 00 7c fb bd ba 00 00 00 02 49 |.IDAT..|.......I|
000000c0 44 41 54 ff ff c2 dd af 45 00 00 00 02 49 44 41 |DAT.....E....IDA|
...
( 00 00 00 02 49 44 41 54 ff ff c2 dd af 45 00 00 00 02 49 44 41 54 02 00 4e cd df 38 00 00 00 02 49 44 41 54 00 00 7c fb bd ba repeats forever)
encoder.write_header().unwrap().into_stream_writer_with_size(2);
The with_size refers to the internal encoding buffer for IDAT so 2 is definitely far too small. However it should still not loop. The problem appears to be that at some point deflate::write::ZlibEncoder::flush is called which then loops around calls to ChunkWriter::write without terminating. I believe this is a bug in deflate.
Should I open a second bug for better documenting the behavior of into_stream_writer_with_size and in particular specify the minimal size it can be called with ?
There is no actual minimum size just a very inefficient size. Improving the documentation could definitely help here, noting that the provided size is the number of bytes of content in the generated IDAT chunks. So using 2 leads to an overhead of literally 600%.
I'm no longer able to reproduce this issue. It seems to have been fixed