pako icon indicating copy to clipboard operation
pako copied to clipboard

Inflate works incorrectly with the Z_SYNC_FLUSH flag

Open kirill-782 opened this issue 2 years ago • 1 comments

After the data has been sent to the push method with the Z_SYNC_FLUSH flag, no data appears in result. At the same time, Zlib node js does a good job on the same piece of data. Test code and file: test.zip I guess the problem is that zlib returns Z_OK instead of Z_STREAM_END.

kirill-782 avatar Sep 30 '22 17:09 kirill-782

Same with deflate. I'm trying to create a deflate file that is not closed so that later I can concatenate multiple such files together. Here is a sample to reproduce:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Encode to DEFLATE online demo</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.11/pako.min.js" integrity="sha256-Kc+gVCuYZLZkDP3MjxWxhNtkMbUy2ycCo86X5fKn/Bw=" crossorigin="anonymous"></script>
<!--    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pako.js" crossorigin="anonymous"></script>-->
    <script>
        function download(text, name, type) {
            const a = document.getElementById("a");
            const file = new Blob([text], {type: type});
            a.href = URL.createObjectURL(file);
            a.download = name;
        }

        function encodeToDeflate() {
            const payload = document.getElementById('raw').value;
            const compressLevel = document.getElementById('compressLevel').value;
            let deflator = new pako.Deflate({raw: true, level: compressLevel});
            deflator.push(payload, pako.Z_SYNC_FLUSH);
            if (deflator.err) {
                throw new Error(deflator.err);
            }
            console.log(deflator)
            const compressed = deflator.result;
            download(compressed, 'encoded.deflate', 'application/octet-stream; charset=binary')
            const compressResultEl = document.getElementById('compressResult');
            compressResultEl.style.visibility = 'visible';
            document.getElementById('originalSize').innerHTML = payload.length;
            document.getElementById('compressedSize').innerHTML = compressed.length.toString();
//             var restored = pako.inflate(binaryString, { to: 'string' });
//             console.log(restored);
        }
    </script>
</head>
<body>
<div>
    <label for="raw">Paste content to encode here:</label>
    <textarea id="raw" style="width: 100%; height: 40vw"></textarea>
</div>
<div>
    <label for="compressLevel">Compress Level</label>
    <select id="compressLevel">
        <option value="0">0 No Compression</option>
        <option value="1">1 Fastest</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6 Default for gzip</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9" selected>9</option>
    </select>
    <button onclick="encodeToDeflate()">Encode to DEFLATE</button>
</div>
<div id="compressResult" style="visibility: hidden">
    <div>
        Original size: <span id="originalSize"></span>
        Compressed size: <span id="compressedSize"></span>
    </div>
    <div>
        <a href="" id="a">Click here to download your file DEFLATE</a>
    </div>
</div>

</body>
</html>

If you comment out the old 1 version and uncomment the 2 version then it will fail because the result field is absent if deflator.

yurtpage avatar Feb 25 '24 14:02 yurtpage