pako
pako copied to clipboard
Inflate works incorrectly with the Z_SYNC_FLUSH flag
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
.
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.