Skip to content

Commit

Permalink
zlib: fix assert on bad input
Browse files Browse the repository at this point in the history
The following test case occasionally triggered an assert because
write_in_progress_ didn't get cleared on error:

  $ cat test.js
  require('zlib').gunzip('BAM', console.log);
  setTimeout(gc, 10);

  $ while true; do node --expose-gc test.js || break; done
  { [Error: incorrect header check] errno: -3, code: 'Z_DATA_ERROR' }
  Assertion failed: (!write_in_progress_ && "write in progress"),
  function Clear, file ../src/node_zlib.cc, line 71.
  Abort trap: 6

Steps to avoid that:

* Initialize all primitive member fields in the constructor.
* Clear the write_in_progress_ member field in ZCtx::Error().
* Ref the ZCtx object as soon as write_in_progress_ is set to true.
  Before this commit, it could get GC'ed in the time between setting
  the field and the call to ctx->Ref().

Fixes nodejs#4783.
  • Loading branch information
bnoordhuis committed Feb 21, 2013
1 parent 9d45b94 commit ef94521
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/node_zlib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,22 @@ void InitZlib(v8::Handle<v8::Object> target);
class ZCtx : public ObjectWrap {
public:

ZCtx(node_zlib_mode mode) : ObjectWrap(), dictionary_(NULL), mode_(mode) {}
ZCtx(node_zlib_mode mode)
: ObjectWrap()
, init_done_(false)
, level_(0)
, windowBits_(0)
, memLevel_(0)
, strategy_(0)
, err_(0)
, dictionary_(NULL)
, dictionary_len_(0)
, flush_(0)
, chunk_size_(0)
, write_in_progress_(false)
, mode_(mode)
{
}


~ZCtx() {
Expand Down Expand Up @@ -108,6 +123,7 @@ class ZCtx : public ObjectWrap {

assert(!ctx->write_in_progress_ && "write already in progress");
ctx->write_in_progress_ = true;
ctx->Ref();

unsigned int flush = args[0]->Uint32Value();
Bytef *in;
Expand Down Expand Up @@ -155,8 +171,6 @@ class ZCtx : public ObjectWrap {
ZCtx::Process,
ZCtx::After);

ctx->Ref();

return ctx->handle_;
}

Expand Down Expand Up @@ -269,6 +283,7 @@ class ZCtx : public ObjectWrap {
MakeCallback(ctx->handle_, onerror_sym, ARRAY_SIZE(args), args);

// no hope of rescue.
ctx->write_in_progress_ = false;
ctx->Unref();
}

Expand Down

0 comments on commit ef94521

Please sign in to comment.