0

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.

2 Answers 2

0

Your data is an incomplete zlib stream. The reported error is correct. The issue is in the Java code, which is not checking for finished(), and in whatever is generating the incomplete zlib stream in the first place.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your response. Unfortunately this is the compressed payload I received via a Apache Pulsar message, so no clue why the data is incomplete.
You asked what's going on. That's what's going on.
It is indeed an incomplete zlib stream. However you can make the NodeJS zlib paly a bit more nicely using the finishFlush option. So in the end, the data is decompressed using: const uncompressedData: Buffer = inflateSync(compressed, { finishFlush: 1 });
You can add your own answer to your question, and accept it.
0

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 });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.