Prevent stack overflows while parsing.

This commit is contained in:
James Coglan
2011-12-17 15:13:09 +00:00
parent 06f4c51a5b
commit 2fa34ef097
2 changed files with 40 additions and 60 deletions
+35 -43
View File
@@ -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;
}
}
},
@@ -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) {