image-png icon indicating copy to clipboard operation
image-png copied to clipboard

[bug] infinite loop in into_stream_writer_with_size

Open lovasoa opened this issue 5 years ago • 3 comments
trafficstars

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)

lovasoa avatar May 17 '20 22:05 lovasoa

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.

197g avatar May 18 '20 18:05 197g

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 ?

lovasoa avatar May 18 '20 20:05 lovasoa

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%.

197g avatar May 18 '20 21:05 197g

I'm no longer able to reproduce this issue. It seems to have been fixed

fintelia avatar Oct 15 '23 05:10 fintelia