I have a 22 byte payload that is compressed with ZLIB. I can decompress the file just fine in Java to the original 14 byte String using this snippet:
public static void main(String[] args) throws Exception {
byte[] compressedData = readFile(INPUT_FILE);
System.out.println("Compressed data (hex): " + bytesToHex(compressedData));
System.out.println("Compressed data length: " + compressedData.length);
byte[] uncompressedData = inflateData(compressedData, UNCOMPRESSED_LENGTH);
String outputString = new String(uncompressedData);
System.out.println("Uncompressed data: " + outputString);
}
public static byte[] readFile(String filePath) throws IOException {
try (FileInputStream fis = new FileInputStream(filePath); FileChannel fileChannel = fis.getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate((int) fileChannel.size());
fileChannel.read(buffer);
return buffer.array();
}
}
public static byte[] inflateData(byte[] compressedData, int uncompressedLength) throws DataFormatException, IOException {
Inflater inflater = new Inflater();
inflater.setInput(compressedData);
byte[] uncompressedData = new byte[uncompressedLength];
int resultLength = inflater.inflate(uncompressedData);
if (resultLength != uncompressedLength) {
throw new IOException("Unexpected uncompressed length: expected " + uncompressedLength + ", got " + resultLength);
}
inflater.end();
return uncompressedData;
}
However in NodeJS I fail to inflate this file. I've tried playing around with the options and also tried Pako, but to no avail.
const compressed = fs.readFileSync(INPUT_FILE);
console.log(`Compressed data (hex): ${compressed.toString('hex')}`);
console.log(`Compressed data length: ${compressed.length}`);
const uncompressedData: Buffer = await inflateAsync(compressed);
console.log(`Decompressed data length: ${uncompressedData.length}`);
if (uncompressedData.length !== UNCOMPRESSED_LENGTH) {
throw new Error(`Unexpected uncompressed length: expected ${UNCOMPRESSED_LENGTH}, got ${uncompressedData.length}`);
}
The current error is Error: unexpected end of file
. I'm more than a bit stuck on this, do you have a clue what's going on?
FYI: the hexadecimal string of this 22 byte file is 789cf2cacfc8cbab5408c928cd4b492d02000000ffff
and is outputted identical in both the Java and NodeJS code.
It is indeed an incomplete zlib stream. However you can make the NodeJS zlib play a bit more nicely using the finishFlush option. So in the end, the data is decompressed using:
const uncompressedData: Buffer = inflateSync(compressed, { finishFlush: 1 });