sile / libflate

A Rust implementation of DEFLATE algorithm and related formats (ZLIB, GZIP)

Home Page:https://docs.rs/libflate

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Empty distance code table may cause problems on Windows 10

mvdnes opened this issue · comments

In my zip-rs crate I use your library to create compressed zip files. Recently an issue (zip-rs/zip#99) was submitted which led me to believe Windows (at least Windows 10) does not like it when the distance codes table is empty. With an empty distance code table, I mean that 'hdist' is 0(+1) and that the single distance code has length 0.

This occurs when compressing the following text (without any newlines):

Windows will show an error when trying to extract this file.

The resulting data is

00000000: 0540 d109 8040 085d e54d d03a 7d1f 6529  .@...@.].M.:}.e)
00000010: 8882 3eb0 b63f 4e8b 3ba7 31e6 8ed6 1cac  ..>..?N.;.1.....
00000020: 8054 6561 5402 acdf e205 13f2 b1d6 4550  .TeaT.........EP
00000030: adf1 98cb b101                           ......

I have analysed this code, and manually set hdist to 7(+1) added 8 distance codes all with length 3. The resulting stream is:

00000000: 0547 d109 8040 085d e54d d03a 7d1f 6529  .G...@.].M.:}.e)
00000010: 8882 3eb0 b6bf f7de 7bef bdd3 e2ce 698c  ..>.....{.....i.
00000020: b9a3 3507 2b20 5559 1895 00eb b778 c184  ..5.+ UY.....x..
00000030: 7cac 7511 546b 3ce6 726c 00              |.u.Tk<.rl.

When putting this stream in a zip file, Windows can extract it just fine.

After reading the RFC, it seems that having no distance codes is allowed. However, I would like to be able to force having at least two distance codes, as many other utilities seem to do this by default.

It seems to be allowed for deflate/zlib, but not for zip:
https://github.com/zlib-ng/zlib-ng/blob/a9f5d668f692f894e89256ec3696c55c131510ed/trees.c#L565

It's a bit of an edge case. In zlib, miniz, miniz_oxide and deflate-rs there being zero distance codes would result in a outputting a stored or static block, unless the compressor is explicitly set to only do huffman and no length matching, as one of those would take up less space. Zlib seems to have some code for this edge-case though.

@mvdnes @oyvindln Thank you for reporting this problem and giving me helpful information for solving it.

I created a PR (#24) for fixing this problem.
This branch seems to work well in my environment (Windows 10). But I would very appreciate it if you could test this branch. > @mvdnes

Thank you for this fix!
My tests indicate that the zips now work on Windows, so I would be very happy if this could be included.

@mvdnes Thank you very much! I merged the PR and published v0.1.21 to crates.io.

Thank you for the quick response!