Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
zlib: fix error reporting
Browse files Browse the repository at this point in the history
This commit is a back-port of the changes on the master branch.

Fixes #3230.
  • Loading branch information
bnoordhuis committed May 9, 2012
1 parent 8c758e1 commit ee437c0
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 69 deletions.
70 changes: 60 additions & 10 deletions lib/zlib.js
Expand Up @@ -50,6 +50,22 @@ Object.keys(binding).forEach(function(k) {
if (k.match(/^Z/)) exports[k] = binding[k];
});

// translation table for return codes.
exports.codes = {
Z_OK: binding.Z_OK,
Z_STREAM_END: binding.Z_STREAM_END,
Z_NEED_DICT: binding.Z_NEED_DICT,
Z_ERRNO: binding.Z_ERRNO,
Z_STREAM_ERROR: binding.Z_STREAM_ERROR,
Z_DATA_ERROR: binding.Z_DATA_ERROR,
Z_MEM_ERROR: binding.Z_MEM_ERROR,
Z_BUF_ERROR: binding.Z_BUF_ERROR,
Z_VERSION_ERROR: binding.Z_VERSION_ERROR
};

Object.keys(exports.codes).forEach(function(k) {
exports.codes[exports.codes[k]] = k;
});

exports.Deflate = Deflate;
exports.Inflate = Inflate;
Expand Down Expand Up @@ -135,7 +151,7 @@ function zlibBuffer(engine, buffer, callback) {

function onEnd() {
var buffer;
switch(buffers.length) {
switch (buffers.length) {
case 0:
buffer = new Buffer(0);
break;
Expand Down Expand Up @@ -169,45 +185,45 @@ function zlibBuffer(engine, buffer, callback) {
// minimal 2-byte header
function Deflate(opts) {
if (!(this instanceof Deflate)) return new Deflate(opts);
Zlib.call(this, opts, binding.Deflate);
Zlib.call(this, opts, binding.DEFLATE);
}

function Inflate(opts) {
if (!(this instanceof Inflate)) return new Inflate(opts);
Zlib.call(this, opts, binding.Inflate);
Zlib.call(this, opts, binding.INFLATE);
}



// gzip - bigger header, same deflate compression
function Gzip(opts) {
if (!(this instanceof Gzip)) return new Gzip(opts);
Zlib.call(this, opts, binding.Gzip);
Zlib.call(this, opts, binding.GZIP);
}

function Gunzip(opts) {
if (!(this instanceof Gunzip)) return new Gunzip(opts);
Zlib.call(this, opts, binding.Gunzip);
Zlib.call(this, opts, binding.GUNZIP);
}



// raw - no header
function DeflateRaw(opts) {
if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts);
Zlib.call(this, opts, binding.DeflateRaw);
Zlib.call(this, opts, binding.DEFLATERAW);
}

function InflateRaw(opts) {
if (!(this instanceof InflateRaw)) return new InflateRaw(opts);
Zlib.call(this, opts, binding.InflateRaw);
Zlib.call(this, opts, binding.INFLATERAW);
}


// auto-detect header.
function Unzip(opts) {
if (!(this instanceof Unzip)) return new Unzip(opts);
Zlib.call(this, opts, binding.Unzip);
Zlib.call(this, opts, binding.UNZIP);
}


Expand All @@ -216,7 +232,7 @@ function Unzip(opts) {
// true or false if there is anything in the queue when
// you call the .write() method.

function Zlib(opts, Binding) {
function Zlib(opts, mode) {
this._opts = opts = opts || {};
this._queue = [];
this._processing = false;
Expand Down Expand Up @@ -263,7 +279,23 @@ function Zlib(opts, Binding) {
}
}

this._binding = new Binding();
this._binding = new binding.Zlib(mode);

var self = this;
this._binding.onerror = function(message, errno) {
// there is no way to cleanly recover.
// continuing only obscures problems.
self._binding = null;
self._hadError = true;
self._queue.length = 0;
self._processing = false;

var error = new Error(message);
error.errno = errno;
error.code = exports.codes[errno];
self.emit('error', error);
};

this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS,
opts.level || exports.Z_DEFAULT_COMPRESSION,
opts.memLevel || exports.Z_DEFAULT_MEMLEVEL,
Expand All @@ -278,6 +310,8 @@ function Zlib(opts, Binding) {
util.inherits(Zlib, stream.Stream);

Zlib.prototype.write = function write(chunk, cb) {
if (this._hadError) return true;

if (this._ended) {
return this.emit('error', new Error('Cannot write after end'));
}
Expand Down Expand Up @@ -306,12 +340,18 @@ Zlib.prototype.write = function write(chunk, cb) {
return empty;
};

Zlib.prototype.reset = function reset() {
return this._binding.reset();
};

Zlib.prototype.flush = function flush(cb) {
this._flush = binding.Z_SYNC_FLUSH;
return this.write(cb);
};

Zlib.prototype.end = function end(chunk, cb) {
if (this._hadError) return true;

var self = this;
this._ending = true;
var ret = this.write(chunk, function() {
Expand All @@ -323,6 +363,8 @@ Zlib.prototype.end = function end(chunk, cb) {
};

Zlib.prototype._process = function() {
if (this._hadError) return;

if (this._processing || this._paused) return;

if (this._queue.length === 0) {
Expand Down Expand Up @@ -360,6 +402,8 @@ Zlib.prototype._process = function() {
this._processing = req;

function callback(availInAfter, availOutAfter, buffer) {
if (self._hadError) return;

var have = availOutBefore - availOutAfter;

assert(have >= 0, 'have should not go down');
Expand Down Expand Up @@ -416,6 +460,12 @@ Zlib.prototype.resume = function() {
this._process();
};

Zlib.prototype.destroy = function() {
this.readable = false;
this.writable = false;
this._ended = true;
};

util.inherits(Deflate, Zlib);
util.inherits(Inflate, Zlib);
util.inherits(Gzip, Zlib);
Expand Down

0 comments on commit ee437c0

Please sign in to comment.