[go: nahoru, domu]

Skip to content

Commit

Permalink
Make sure Pako always has enough room
Browse files Browse the repository at this point in the history
Previously, we used a fixed chunkSize of 100KiB for Pako's output
buffer.  Using a hardcoded size caused issues, since Pako would assume
we wanted to use multiple chunks, and we didn't deal with this.  Now,
`Inflator#inflate()` takes a new `expected` argument, which indicates
the expected output size.  If this is bigger than the current chunkSize,
Inflator allocates a new output buffer that's big enough to hold the
output.

Fixes novnc#531
  • Loading branch information
DirectXMan12 committed Sep 23, 2015
1 parent 40b35fa commit c802d93
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 21 deletions.
2 changes: 1 addition & 1 deletion docs/notes
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ Rebuilding inflator.js

- Download pako from npm
- Install browserify using npm
- browserify utils/inflator.partial.js -o include/inflator.js
- browserify utils/inflator.partial.js -o include/inflator.js -s inflator
35 changes: 22 additions & 13 deletions include/inflator.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ module.exports = function inflate_fast(strm, start) {
var wsize; /* window size or zero if not using window */
var whave; /* valid bytes in the window */
var wnext; /* window write index */
var window; /* allocated sliding window, if wsize != 0 */
// Use `s_window` instead `window`, avoid conflict with instrumentation tools
var s_window; /* allocated sliding window, if wsize != 0 */
var hold; /* local strm.hold */
var bits; /* local strm.bits */
var lcode; /* local strm.lencode */
Expand Down Expand Up @@ -268,7 +269,7 @@ module.exports = function inflate_fast(strm, start) {
wsize = state.wsize;
whave = state.whave;
wnext = state.wnext;
window = state.window;
s_window = state.window;
hold = state.hold;
bits = state.bits;
lcode = state.lencode;
Expand Down Expand Up @@ -386,13 +387,13 @@ module.exports = function inflate_fast(strm, start) {
//#endif
}
from = 0; // window index
from_source = window;
from_source = s_window;
if (wnext === 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
output[_out++] = window[from++];
output[_out++] = s_window[from++];
} while (--op);
from = _out - dist; /* rest from output */
from_source = output;
Expand All @@ -404,14 +405,14 @@ module.exports = function inflate_fast(strm, start) {
if (op < len) { /* some from end of window */
len -= op;
do {
output[_out++] = window[from++];
output[_out++] = s_window[from++];
} while (--op);
from = 0;
if (wnext < len) { /* some from start of window */
op = wnext;
len -= op;
do {
output[_out++] = window[from++];
output[_out++] = s_window[from++];
} while (--op);
from = _out - dist; /* rest from output */
from_source = output;
Expand All @@ -423,7 +424,7 @@ module.exports = function inflate_fast(strm, start) {
if (op < len) { /* some from window */
len -= op;
do {
output[_out++] = window[from++];
output[_out++] = s_window[from++];
} while (--op);
from = _out - dist; /* rest from output */
from_source = output;
Expand Down Expand Up @@ -2371,9 +2372,9 @@ function ZStream() {

module.exports = ZStream;

},{}],"/partial_inflator.js":[function(require,module,exports){
var zlib = require('./lib/zlib/inflate.js');
var ZStream = require('./lib/zlib/zstream.js');
},{}],8:[function(require,module,exports){
var zlib = require('../node_modules/pako/lib/zlib/inflate.js');
var ZStream = require('../node_modules/pako/lib/zlib/zstream.js');

var Inflate = function () {
this.strm = new ZStream();
Expand All @@ -2385,12 +2386,20 @@ var Inflate = function () {
};

Inflate.prototype = {
inflate: function (data, flush) {
inflate: function (data, flush, expected) {
this.strm.input = data;
this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0;
this.strm.next_out = 0;

// resize our output buffer if it's too small
// (we could just use multiple chunks, but that would cause an extra
// allocation each time to flatten the chunks)
if (expected > this.chunkSize) {
this.chunkSize = expected;
this.strm.output = new Uint8Array(this.chunkSize);
}

this.strm.avail_out = this.chunkSize;

zlib.inflate(this.strm, flush);
Expand All @@ -2405,5 +2414,5 @@ Inflate.prototype = {

module.exports = {Inflate: Inflate};

},{"./lib/zlib/inflate.js":5,"./lib/zlib/zstream.js":7}]},{},[])("/partial_inflator.js")
});
},{"../node_modules/pako/lib/zlib/inflate.js":5,"../node_modules/pako/lib/zlib/zstream.js":7}]},{},[8])(8)
});
9 changes: 5 additions & 4 deletions include/rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -1688,16 +1688,17 @@ var RFB;

var resetStreams = 0;
var streamId = -1;
var decompress = function (data) {
var decompress = function (data, expected) {
for (var i = 0; i < 4; i++) {
if ((resetStreams >> i) & 1) {
this._FBU.zlibs[i].reset();
console.debug('RESET!');
Util.Info("Reset zlib stream " + i);
}
}

//var uncompressed = this._FBU.zlibs[streamId].uncompress(data, 0);
var uncompressed = this._FBU.zlibs[streamId].inflate(data, true);
var uncompressed = this._FBU.zlibs[streamId].inflate(data, true, expected);
/*if (uncompressed.status !== 0) {
Util.Error("Invalid data in zlib stream");
}*/
Expand Down Expand Up @@ -1830,7 +1831,7 @@ var RFB;
if (raw) {
data = this._sock.rQshiftBytes(cl_data);
} else {
data = decompress(this._sock.rQshiftBytes(cl_data));
data = decompress(this._sock.rQshiftBytes(cl_data), rowSize * this._FBU.height);
}

// Convert indexed (palette based) image data to RGB
Expand Down Expand Up @@ -1879,7 +1880,7 @@ var RFB;
if (raw) {
data = this._sock.rQshiftBytes(cl_data);
} else {
data = decompress(this._sock.rQshiftBytes(cl_data));
data = decompress(this._sock.rQshiftBytes(cl_data), uncompressedSize);
}

this._display.blitRgbImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, data, 0, false);
Expand Down
14 changes: 11 additions & 3 deletions utils/inflator.partial.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var zlib = require('./lib/zlib/inflate.js');
var ZStream = require('./lib/zlib/zstream.js');
var zlib = require('../node_modules/pako/lib/zlib/inflate.js');
var ZStream = require('../node_modules/pako/lib/zlib/zstream.js');

var Inflate = function () {
this.strm = new ZStream();
Expand All @@ -11,12 +11,20 @@ var Inflate = function () {
};

Inflate.prototype = {
inflate: function (data, flush) {
inflate: function (data, flush, expected) {
this.strm.input = data;
this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0;
this.strm.next_out = 0;

// resize our output buffer if it's too small
// (we could just use multiple chunks, but that would cause an extra
// allocation each time to flatten the chunks)
if (expected > this.chunkSize) {
this.chunkSize = expected;
this.strm.output = new Uint8Array(this.chunkSize);
}

this.strm.avail_out = this.chunkSize;

zlib.inflate(this.strm, flush);
Expand Down

0 comments on commit c802d93

Please sign in to comment.