1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

Fix parser being reset in case (p)message_buffer is attached

without the parser set to return buffers.

This might result in corrupt data if the listener is attached
while the parser holds partial data.
This commit is contained in:
Ruben Bridgewater
2017-01-15 12:53:09 +01:00
parent 670b774101
commit dffa8a6aee
3 changed files with 67 additions and 43 deletions

View File

@@ -1,6 +1,12 @@
Changelog Changelog
========= =========
## v.2.6.5 - 15 Jan, 2017
Bugfixes
- Fixed parser reset if (p)message_buffer listener is attached
## v.2.6.4 - 12 Jan, 2017 ## v.2.6.4 - 12 Jan, 2017
Bugfixes Bugfixes

View File

@@ -171,10 +171,16 @@ function RedisClient (options, stream) {
'The drain event listener is deprecated and will be removed in v.3.0.0.\n' + 'The drain event listener is deprecated and will be removed in v.3.0.0.\n' +
'If you want to keep on listening to this event please listen to the stream drain event directly.' 'If you want to keep on listening to this event please listen to the stream drain event directly.'
); );
} else if (event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer' && !this.buffers) { } else if ((event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer') && !this.buffers && !this.message_buffers) {
if (this.reply_parser.name !== 'javascript') {
return this.warn(
'You attached the ' + event + ' without the hiredis parser without the returnBuffers option set to true.\n' +
'Please use the JavaScript parser or set the returnBuffers option to true to return buffers.'
);
}
this.reply_parser.optionReturnBuffers = true;
this.message_buffers = true; this.message_buffers = true;
this.handle_reply = handle_detect_buffers_reply; this.handle_reply = handle_detect_buffers_reply;
this.reply_parser = create_parser(this);
} }
}); });
} }

View File

@@ -508,52 +508,64 @@ describe('publish/subscribe', function () {
}); });
it('allows to listen to pmessageBuffer and pmessage', function (done) { it('allows to listen to pmessageBuffer and pmessage', function (done) {
var batch = sub.batch();
var end = helper.callFuncAfter(done, 6); var end = helper.callFuncAfter(done, 6);
assert.strictEqual(sub.message_buffers, false); var data = Array(10000).join('äüs^öéÉÉ`e');
batch.psubscribe('*'); sub.set('foo', data, function () {
batch.subscribe('/foo'); sub.get('foo');
batch.unsubscribe('/foo'); sub.stream.once('data', function () {
batch.unsubscribe(helper.isNull()); assert.strictEqual(sub.message_buffers, false);
batch.subscribe(['/foo'], helper.isString('/foo')); assert.strictEqual(sub.shouldBuffer, false);
batch.exec(); sub.on('pmessageBuffer', function (pattern, channel, message) {
assert.strictEqual(sub.shouldBuffer, false); if (parser !== 'javascript' && typeof pattern === 'string') {
sub.on('pmessageBuffer', function (pattern, channel, message) { pattern = new Buffer(pattern);
assert.strictEqual(pattern.inspect(), new Buffer('*').inspect()); channel = new Buffer(channel);
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect()); }
sub.quit(end); assert.strictEqual(pattern.inspect(), new Buffer('*').inspect());
}); assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
// Either message_buffers or buffers has to be true, but not both at the same time sub.quit(end);
assert.notStrictEqual(sub.message_buffers, sub.buffers); });
sub.on('pmessage', function (pattern, channel, message) { if (parser === 'javascript') {
assert.strictEqual(pattern, '*'); assert.notStrictEqual(sub.message_buffers, sub.buffers);
assert.strictEqual(channel, '/foo'); }
assert.strictEqual(message, 'hello world');
end(); });
}); var batch = sub.batch();
sub.on('message', function (channel, message) { batch.psubscribe('*');
assert.strictEqual(channel, '/foo'); batch.subscribe('/foo');
assert.strictEqual(message, 'hello world'); batch.unsubscribe('/foo');
end(); batch.unsubscribe(helper.isNull());
}); batch.subscribe(['/foo'], helper.isString('/foo'));
setTimeout(function () { batch.exec(function () {
pub.pubsub('numsub', '/foo', function (err, res) { pub.pubsub('numsub', '/foo', function (err, res) {
// There's one subscriber to this channel // There's one subscriber to this channel
assert.deepEqual(res, ['/foo', 1]); assert.deepEqual(res, ['/foo', 1]);
end();
});
pub.pubsub('channels', function (err, res) {
// There's exactly one channel that is listened too
assert.deepEqual(res, ['/foo']);
end();
});
pub.pubsub('numpat', function (err, res) {
// One pattern is active
assert.strictEqual(res, 1);
end();
});
pub.publish('/foo', 'hello world', helper.isNumber(2));
});
// Either message_buffers or buffers has to be true, but not both at the same time
sub.on('pmessage', function (pattern, channel, message) {
assert.strictEqual(pattern, '*');
assert.strictEqual(channel, '/foo');
assert.strictEqual(message, 'hello world');
end(); end();
}); });
pub.pubsub('channels', function (err, res) { sub.on('message', function (channel, message) {
// There's exactly one channel that is listened too assert.strictEqual(channel, '/foo');
assert.deepEqual(res, ['/foo']); assert.strictEqual(message, 'hello world');
end(); end();
}); });
pub.pubsub('numpat', function (err, res) { });
// One pattern is active
assert.strictEqual(res, 1);
end();
});
pub.publish('/foo', 'hello world', helper.isNumber(2));
}, 50);
}); });
}); });