Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closing zlib stream may throw uncaught exception #15625

Closed
nakedible-p opened this issue Sep 26, 2017 · 11 comments
Closed

Closing zlib stream may throw uncaught exception #15625

nakedible-p opened this issue Sep 26, 2017 · 11 comments
Labels
confirmed-bug Issues with confirmed bugs. stream Issues and PRs related to the stream subsystem. zlib Issues and PRs related to the zlib subsystem.

Comments

@nakedible-p
Copy link

When calling .close() on a zlib.createGunzip() stream while the engine is still working on decompressing some stuff, sometimes this exception is thrown:

zlib.js:633
      var newReq = self._handle.write(flushFlag,
                               ^

TypeError: Cannot read property 'write' of null
    at Zlib.callback (zlib.js:633:32)

Looking at the code, it seems that when _processChunk sets a callback, it does not sufficiently check that this._handle has not been unset in the meantime. The earlier code has assert(this._handle, 'zlib binding closed'); check, but the callback code does not.

But even the assert is wrong, as calling .close() on a stream, even when there's unprocessed data, should not throw any exceptions. I guess the function should check for this._closed similarily as it checks for this._hadError currently.

Unfortunately this bug is triggered very rarely on a production system, so I haven't been able to write short code to reproduce the issue.

@mscdex mscdex added the zlib Issues and PRs related to the zlib subsystem. label Sep 26, 2017
@Fishrock123 Fishrock123 added the stream Issues and PRs related to the stream subsystem. label Sep 26, 2017
@Fishrock123
Copy link
Contributor

Sounds like it may be a good idea to attach an appropriate 'error' event listener on the stream if possible?

cc @nodejs/streams as there could still be an issue in here

@nakedible-p
Copy link
Author

Adding an 'error' listener does nothing as the error is not emitted. Instead, it is thrown from callback that is invoked by the zlib binding, meaning that the only way to catch it is process.on('uncaughtException').

That said, even if the error listener would work, there is still a bug here - closing a stream should not emit an error either.

@mcollina
Copy link
Member

I think this is fixed in 8: https://github.com/nodejs/node/blob/master/lib/zlib.js#L465-L484 vs https://github.com/nodejs/node/blob/v6.x/lib/zlib.js#L622-L643. The PR is #13322, but that's not easily backportable, so we might want to do an ad-hoc fix for Node 6.

@Fishrock123 Fishrock123 added confirmed-bug Issues with confirmed bugs. v6.x labels Sep 27, 2017
@nakedible-p
Copy link
Author

True, this seems fixed in 8. Would need testing to be sure, but unfortunately switching to 8 would be really difficult.

FWIW: We are currently testing stream._hadError = true; stream.close() as an ugly hack to fix this. Not sure of the results yet.

@nakedible-p
Copy link
Author

I can definitely confirm that using stream._hadError = true; before closing the stream is a workaround that fixes the issue. Hopefully something similar could be implemented in to 6.x.

@mcollina
Copy link
Member

@nakedible-p would you like to send a PR?

@MylesBorins
Copy link
Contributor

@nakedible-p we are putting out an r.c. for the next 6.x today. If you can get a PR in within the next week we can get it in a future RC before the release

@nakedible-p
Copy link
Author

I can do a fix PR for certain, but I have no idea how I would write a testcase for this. If a simple fix is fine, I'll get it done right away.

@mcollina
Copy link
Member

@Trott #13322 fixed this. We need a separate fix for this one as well.

@nakedible-p
Copy link
Author

@MylesBorins @mcollina There is now an extremely minimal fix PR. Let me know what else should I do.

nakedible-p pushed a commit to nakedible-p/node that referenced this issue Nov 14, 2017
Closing a zlib stream may throw an uncaught exception afterwards if
there was a pending callback still to be invoked. This adds a very
minimal fix to the issue as all of this code has been rewritten in later
versions.

Fixes: nodejs#15625
MylesBorins pushed a commit that referenced this issue Jan 19, 2018
Closing a zlib stream may throw an uncaught exception afterwards if
there was a pending callback still to be invoked. This adds a very
minimal fix to the issue as all of this code has been rewritten in later
versions.

Fixes: #15625
PR-URL: #16312
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this issue Feb 11, 2018
Closing a zlib stream may throw an uncaught exception afterwards if
there was a pending callback still to be invoked. This adds a very
minimal fix to the issue as all of this code has been rewritten in later
versions.

Fixes: #15625
PR-URL: #16312
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@apapirovski
Copy link
Member

Looks like this was resolved in #16312 — no clue why it didn't autoclose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. stream Issues and PRs related to the stream subsystem. zlib Issues and PRs related to the zlib subsystem.
Projects
None yet
Development

No branches or pull requests

6 participants