Browse Source

zlib: fix assert on bad input

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 #4783.
v0.8.21-release
Ben Noordhuis 12 years ago
parent
commit
ef94521909
  1. 21
      src/node_zlib.cc

21
src/node_zlib.cc

@ -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() {
@ -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;
@ -155,8 +171,6 @@ class ZCtx : public ObjectWrap {
ZCtx::Process,
ZCtx::After);
ctx->Ref();
return ctx->handle_;
}
@ -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();
}

Loading…
Cancel
Save