Node: zlib deflate/inflate failure

Created on 15 Dec 2019  Â·  5Comments  Â·  Source: nodejs/node

Hi,

I reported an issue against ws (https://github.com/websockets/ws/issues/1669) which actually can be traced back to NodeJS (https://github.com/nodejs/node/commit/851a691678 - https://github.com/nodejs/node/pull/26363), introduced from 11.10.1 to 11.11.0.

Essentially there is some deflate'd data that cannot be uncompressed successfully. I hope it's okay to point to related issue for code samples and further discussion. If not please tell - I'll extend this report.

zlib

Most helpful comment

Here is a test case:

const zlib = require('zlib');

const data = zlib.deflateRawSync('Welcome');

const chunks = [];
const inflate = zlib.createInflateRaw();

inflate.on('data', function(chunk) {
  chunks.push(chunk);
});

inflate.write(data);
inflate.write(Buffer.from([0x00, 0x00, 0xff, 0xff]));
inflate.flush(function() {
  const buf = Buffer.concat(chunks);
  console.log(buf.toString());
});

The problem is that inflate.flush() callback is not called. This used to work before https://github.com/nodejs/node/commit/28db96f31c2724b16d6b9bec19c600023365b7cc.

Decompression follows the RFC 7692 specifications.

It is possible to use the 'end' event, for example if

inflate.on('end', function() {
  const buf = Buffer.concat(chunks);
  console.log(buf.toString());
});

is added to the above example it will work as expected but is it intended?

All 5 comments

Here is a test case:

const zlib = require('zlib');

const data = zlib.deflateRawSync('Welcome');

const chunks = [];
const inflate = zlib.createInflateRaw();

inflate.on('data', function(chunk) {
  chunks.push(chunk);
});

inflate.write(data);
inflate.write(Buffer.from([0x00, 0x00, 0xff, 0xff]));
inflate.flush(function() {
  const buf = Buffer.concat(chunks);
  console.log(buf.toString());
});

The problem is that inflate.flush() callback is not called. This used to work before https://github.com/nodejs/node/commit/28db96f31c2724b16d6b9bec19c600023365b7cc.

Decompression follows the RFC 7692 specifications.

It is possible to use the 'end' event, for example if

inflate.on('end', function() {
  const buf = Buffer.concat(chunks);
  console.log(buf.toString());
});

is added to the above example it will work as expected but is it intended?

cc: @addaleax

This isn’t specific to flushes – in

const zlib = require('zlib');

const data = zlib.deflateRawSync('Welcome');

const inflate = zlib.createInflateRaw();

inflate.resume();
inflate.write(data, () => console.log('write 1 done'));
inflate.write(Buffer.from([0x00]), () => console.log('write 2 done'));
inflate.write(Buffer.from([0x00]), () => console.log('write 3 done'));

only the first two writes finish. I’ll try to figure out why that is.

I did not investigate but I think it's because the inflate stream is no longer readable after a block with the BFINAL bit set to 1 is received.

@lpinca Yeah, but other Transform streams seem to still allow writes to finish, even after .push(null). So I’ll look into that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ksushilmaurya picture ksushilmaurya  Â·  3Comments

danialkhansari picture danialkhansari  Â·  3Comments

dfahlander picture dfahlander  Â·  3Comments

seishun picture seishun  Â·  3Comments

danielstaleiny picture danielstaleiny  Â·  3Comments