rust-lang / flate2-rs

DEFLATE, gzip, and zlib bindings for Rust
https://docs.rs/flate2
Apache License 2.0
891 stars 158 forks source link

deflate::Decoder always decompresses whole blocks (seems inefficient, unexpected and even unsecure) #295

Closed radekm closed 2 years ago

radekm commented 2 years ago

It seems that deflate::Decoder always decompresses whole block.

If that is true it means:

Here is an example. Reading 1 byte from 10 MB stream consumes 1.3 GB of memory:

    let mut buf = Vec::new();

    let mut writer = BitWriter::new(Cursor::new(&mut buf));
    writer.write_bits(1, 0);  // Not last block
    writer.write_bits(2, 1);  // Fixed Huffman
    writer.write_bits(8, 0b10001110);  // Literal A

    for _ in 0..6000_000 {
        writer.write_bits(8, 0b10100011);  // Max length
        writer.write_bits(5, 0);  // Distance 1
    }
    // End block.
    writer.write_bits(7, 0);
    writer.flush();

    println!("Written {} compressed bytes", buf.len());

    let mut dec = Decoder::new(buf.as_slice());
    let mut out = [1u8];
    dec.read_exact(&mut out);
radekm commented 2 years ago

This behavior also makes it harder to read corrupted archives (even if you are interested in some prefix which is ok).

radekm commented 2 years ago

This is completely wrong. I was using libflate instead of flate2.

And flate2 behaves correctly.