From 2fa34ef097f376e34297bcb65af4b387755087ff Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sat, 17 Dec 2011 15:13:09 +0000 Subject: [PATCH] Prevent stack overflows while parsing. --- lib/faye/websocket/protocol8_parser.js | 78 +++++++++---------- .../protocol8_parser/stream_reader.js | 22 ++---- 2 files changed, 40 insertions(+), 60 deletions(-) diff --git a/lib/faye/websocket/protocol8_parser.js b/lib/faye/websocket/protocol8_parser.js index ebf346a..cd1dbdb 100644 --- a/lib/faye/websocket/protocol8_parser.js +++ b/lib/faye/websocket/protocol8_parser.js @@ -8,8 +8,6 @@ var Protocol8Parser = function(webSocket, options) { this._reader = new Reader(); this._stage = 0; this._masking = options && options.masking; - - this._drain(); }; var instance = { @@ -74,47 +72,41 @@ var instance = { parse: function(data) { this._reader.put(data); - }, - - _drain: function() { - switch (this._stage) { - case 0: - this._reader.read(1, function(buffer) { - this._parseOpcode(buffer[0]); - this._drain(); - }, this); - break; - - case 1: - this._reader.read(1, function(buffer) { - this._parseLength(buffer[0]); - this._drain(); - }, this); - break; - - case 2: - this._reader.read(this._lengthSize, function(buffer) { - this._parseExtendedLength(buffer); - this._drain(); - }, this); - break; - - case 3: - this._reader.read(4, function(buffer) { - this._mask = buffer; - this._stage = 4; - this._drain(); - }, this); - break; - - case 4: - this._reader.read(this._length, function(buffer) { - this._payload = buffer; - this._emitFrame(); - this._stage = 0; - this._drain(); - }, this); - break; + var buffer = true; + while (buffer) { + switch (this._stage) { + case 0: + buffer = this._reader.read(1); + if (buffer) this._parseOpcode(buffer[0]); + break; + + case 1: + buffer = this._reader.read(1); + if (buffer) this._parseLength(buffer[0]); + break; + + case 2: + buffer = this._reader.read(this._lengthSize); + if (buffer) this._parseExtendedLength(buffer); + break; + + case 3: + buffer = this._reader.read(4); + if (buffer) { + this._mask = buffer; + this._stage = 4; + } + break; + + case 4: + buffer = this._reader.read(this._length); + if (buffer) { + this._payload = buffer; + this._emitFrame(); + this._stage = 0; + } + break; + } } }, diff --git a/lib/faye/websocket/protocol8_parser/stream_reader.js b/lib/faye/websocket/protocol8_parser/stream_reader.js index 8588671..f594aa7 100644 --- a/lib/faye/websocket/protocol8_parser/stream_reader.js +++ b/lib/faye/websocket/protocol8_parser/stream_reader.js @@ -1,28 +1,16 @@ var StreamReader = function() { - this._queue = []; - this._cursor = 0; - this._callbacks = []; + this._queue = []; + this._cursor = 0; }; -StreamReader.prototype.read = function(bytes, callback, context) { - this._callbacks.push([bytes, callback, context]); - this._flush(); +StreamReader.prototype.read = function(bytes) { + return this._readBuffer(bytes); }; StreamReader.prototype.put = function(buffer) { if (!buffer || buffer.length === 0) return; + if (!buffer.copy) buffer = new Buffer(buffer); this._queue.push(buffer); - this._flush(); -}; - -StreamReader.prototype._flush = function() { - var callbacks = this._callbacks, - callback, buffer; - - while (callbacks[0] && (buffer = this._readBuffer(callbacks[0][0]))) { - callback = callbacks.shift(); - callback[1].call(callback[2], buffer); - } }; StreamReader.prototype._readBuffer = function(length) {