From 083e446d23f10ac7064d4bb222c47ce87ade36cc Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sat, 19 Sep 2015 17:40:09 +0200 Subject: [PATCH] Fix parser regression. Out of memory resulted in an endless loop --- lib/parser/javascript.js | 5 +++++ test/parser/javascript.spec.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/parser/javascript.js b/lib/parser/javascript.js index a6ad8892fa..d979ec3cbe 100644 --- a/lib/parser/javascript.js +++ b/lib/parser/javascript.js @@ -220,6 +220,11 @@ ReplyParser.prototype._packetEndOffset = function () { while (this._buffer[offset] !== 0x0d && this._buffer[offset + 1] !== 0x0a) { offset++; + + /* istanbul ignore if: activate the js parser out of memory test to test this */ + if (offset >= this._buffer.length) { + throw new IncompleteReadBuffer("didn't see LF after NL reading multi bulk count (" + offset + " => " + this._buffer.length + ", " + this._offset + ")"); + } } offset++; diff --git a/test/parser/javascript.spec.js b/test/parser/javascript.spec.js index 693ad45f52..19df991675 100644 --- a/test/parser/javascript.spec.js +++ b/test/parser/javascript.spec.js @@ -2,6 +2,8 @@ var assert = require('assert'); var Parser = require("../../lib/parser/javascript").Parser; +var config = require("../lib/config"); +var redis = config.redis; describe('javascript parser', function () { it('handles multi-bulk reply', function (done) { @@ -24,4 +26,36 @@ describe('javascript parser', function () { assert.equal(reply_count, 3, "check reply should have been called three times"); return done(); }); + + // Activate this if you want to fry your cpu / memory + describe.skip("test out of memory", function () { + var args = config.configureClient('javascript', '127.0.0.1'); + var clients = new Array(300).join(" ").split(" "); + var client; + beforeEach(function (done) { + client = redis.createClient.apply(redis.createClient, args); + client.once("connect", function () { + client.flushdb(done); + }); + }); + + it('reach limit and wait for further data', function (done) { + setTimeout(done, 5000); + clients.forEach(function(entry, a) { + var max = 0; + var client = redis.createClient.apply(redis.createClient, args); + client.on('ready', function() { + while (++max < 50) { + var item = []; + for (var i = 0; i < 100; ++i) { + item.push('aaa' + (Math.random() * 1000000 | 0)); + } + client.del('foo' + a); + client.lpush('foo' + a, item); + client.lrange('foo' + a, 0, 99); + } + }); + }); + }); + }); });