ckolivas / lrzip

Long Range Zip

Home Page:http://lrzip.kolivas.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BUG: lz4_compresses function always fails

pete4abw opened this issue · comments

From master 0.640

Starting thread 0 to compress 128700872 bytes from stream 1
lz4 testing FAILED for chunk 128700872. Compressed size = 20480.00% of chunk, 1 Passes
lz4 testing FAILED for chunk 128700872. Compressed size = 20480.00% of chunk, 1 Passes
lz4 testing FAILED for chunk 128700872. Compressed size = 20480.00% of chunk, 1 Passes
lz4 testing FAILED for chunk 128700872. Compressed size = 20480.00% of chunk, 1 Passes
lz4 testing FAILED for chunk 128700872. Compressed size = 20480.00% of chunk, 1 Passes
lz4 testing FAILED for chunk 128700872. Compressed size = 20480.00% of chunk, 1 Passes
lz4 testing FAILED for chunk 13459191. Compressed size = 83886079.96% of chunk, 1 Passes

from 0.631 using lzo1x_compress

lzo testing OK for chunk 128700872. Compressed size = 71.18% of chunk, 1 Passes
lzo testing OK for chunk 128700872. Compressed size = 41.46% of chunk, 1 Passes
lzo testing OK for chunk 128700872. Compressed size = 39.46% of chunk, 1 Passes
lzo testing OK for chunk 128700872. Compressed size = 35.97% of chunk, 1 Passes
lzo testing OK for chunk 128700872. Compressed size = 35.52% of chunk, 1 Passes
lzo testing OK for chunk 128700872. Compressed size = 28.37% of chunk, 1 Passes
lzo testing OK for chunk 13459191. Compressed size = 72.42% of chunk, 1 Passes

The issue appears to be using test_len instead of in_len in test function. Really broken because it will fail on first attempt.

                lz4_ret = LZ4_compress_default((const char *)test_buf, c_buf, test_len, dlen);
                if (!lz4_ret) // Bigger than dlen, no point going further
                        break;
                if (lz4_ret < best_dlen)
                        best_dlen = lz4_ret;
                if (lz4_ret < test_len) {
                        ret = 1;
                        break;
                }

Try this

                lz4_ret = LZ4_compress_default((const char *)test_buf, c_buf, in_len, dlen);
                if (!lz4_ret) // Bigger than dlen, no point going further
                        try again;

Breaking out before test_len is 0 is just wrong

What file are you testing? That is the correct way to use lz4 compress which has different semantics to lzo, but lz4 will be less able to compress compared to lzo.

What file are you testing? That is the correct way to use lz4 compress which has different semantics to lzo, but lz4 will be less able to compress compared to lzo.

Just a kernel source, 5.10.y from git and tar'red. I just cloned this repo and ran. I (no surprise) use a different logic, but it works with lz4 as expected. You must use in_len in the function call and remove the first failure test because if the first test fails, the function will abort. If you decide to fix Threshold testing, you will need to test all parts of the source buffer. Having the !lz4_ret test will abort the run.

Here with in_len

lz4 testing OK for chunk 128700872. Compressed size = 74.64% of chunk, 1 Passes
lz4 testing OK for chunk 128700872. Compressed size = 42.24% of chunk, 1 Passes
lz4 testing OK for chunk 128700872. Compressed size = 39.09% of chunk, 1 Passes
lz4 testing OK for chunk 128700872. Compressed size = 35.25% of chunk, 1 Passes
lz4 testing OK for chunk 128700872. Compressed size = 35.25% of chunk, 1 Passes
lz4 testing OK for chunk 128700872. Compressed size = 27.87% of chunk, 1 Passes

You're right, well spotted. Will have to churn a quick bugfix release. Thanks.

diff --git a/stream.c b/stream.c
index a2ec0f0..61e0fab 100644
--- a/stream.c
+++ b/stream.c
@@ -1907,9 +1907,9 @@ static int lz4_compresses(rzip_control *control, uchar *s_buf, i64 s_len)
                int lz4_ret;
 
                workcounter++;
-               lz4_ret = LZ4_compress_default((const char *)test_buf, c_buf, test_len, dlen);
-               if (!lz4_ret) // Bigger than dlen, no point going further
-                       break;
+               lz4_ret = LZ4_compress_default((const char *)test_buf, c_buf, in_len, dlen);
+       //      if (!lz4_ret) // Bigger than dlen, no point going further
+       //              break;
                if (lz4_ret < best_dlen)
                        best_dlen = lz4_ret;
                if (lz4_ret < test_len) {

Fixed in 0.641 with a reworked lz4_compresses.