Skip to content

Commit 55e4a9b

Browse files
author
Ruben Bridgewater
committed
Fix issues with returning buffers
Fixes #818 and #354
1 parent b900bd6 commit 55e4a9b

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

index.js

+14-11
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,8 @@ function reply_to_strings(reply) {
556556

557557
if (Array.isArray(reply)) {
558558
for (i = 0; i < reply.length; i++) {
559-
if (reply[i] !== null && reply[i] !== undefined) {
560-
reply[i] = reply[i].toString();
561-
}
559+
// Recusivly call the function as slowlog returns deep nested replies
560+
reply[i] = reply_to_strings(reply[i]);
562561
}
563562
return reply;
564563
}
@@ -612,14 +611,17 @@ RedisClient.prototype.return_reply = function (reply) {
612611
} else {
613612
debug("No callback for reply");
614613
}
615-
} else if (this.pub_sub_mode || (command_obj && command_obj.sub_command)) {
614+
} else if (this.pub_sub_mode || command_obj && command_obj.sub_command) {
616615
if (Array.isArray(reply)) {
616+
if (!this.options.return_buffers && (!command_obj || this.options.detect_buffers && command_obj.buffer_args === false)) {
617+
reply = reply_to_strings(reply);
618+
}
617619
type = reply[0].toString();
618620

619621
if (type === "message") {
620-
this.emit("message", reply[1].toString(), reply[2]); // channel, message
622+
this.emit("message", reply[1], reply[2]); // channel, message
621623
} else if (type === "pmessage") {
622-
this.emit("pmessage", reply[1].toString(), reply[2].toString(), reply[3]); // pattern, channel, message
624+
this.emit("pmessage", reply[1], reply[2], reply[3]); // pattern, channel, message
623625
} else if (type === "subscribe" || type === "unsubscribe" || type === "psubscribe" || type === "punsubscribe") {
624626
if (reply[2] === 0) {
625627
this.pub_sub_mode = false;
@@ -629,12 +631,10 @@ RedisClient.prototype.return_reply = function (reply) {
629631
}
630632
// subscribe commands take an optional callback and also emit an event, but only the first response is included in the callback
631633
// TODO - document this or fix it so it works in a more obvious way
632-
// reply[1] can be null
633-
var reply1String = (reply[1] === null) ? null : reply[1].toString();
634634
if (command_obj && typeof command_obj.callback === "function") {
635-
command_obj.callback(null, reply1String);
635+
command_obj.callback(null, reply[1]);
636636
}
637-
this.emit(type, reply1String, reply[2]); // channel, count
637+
this.emit(type, reply[1], reply[2]); // channel, count
638638
} else {
639639
this.emit("error", new Error("subscriptions are active but got unknown reply type " + type));
640640
return;
@@ -644,6 +644,9 @@ RedisClient.prototype.return_reply = function (reply) {
644644
return;
645645
}
646646
} else if (this.monitoring) {
647+
if (Buffer.isBuffer(reply)) {
648+
reply = reply.toString();
649+
}
647650
len = reply.indexOf(" ");
648651
timestamp = reply.slice(0, len);
649652
argindex = reply.indexOf('"');
@@ -776,7 +779,7 @@ RedisClient.prototype.send_command = function (command, args, callback) {
776779

777780
for (i = 0; i < args.length; i += 1) {
778781
arg = args[i];
779-
if (!(Buffer.isBuffer(arg) || arg instanceof String)) {
782+
if (!(Buffer.isBuffer(arg) || typeof arg === 'string')) {
780783
arg = String(arg);
781784
}
782785

test/helper.js

+24-12
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,39 @@ module.exports = {
108108
}
109109
return true;
110110
},
111-
allTests: function (options, cb) {
111+
allTests: function (opts, cb) {
112112
if (!cb) {
113-
cb = options;
114-
options = {};
113+
cb = opts;
114+
opts = {};
115115
}
116-
// TODO: Test all different option cases at some point (e.g. buffers)
117-
// [undefined, { return_buffers: true }].forEach(function (config_options) {
118-
// describe(config_options && config_options.return_buffers ? "returning buffers" : "returning strings", function () {
119-
// });
120-
// });
121116
var parsers = ['javascript'];
122117
var protocols = ['IPv4'];
123118
if (process.platform !== 'win32') {
124119
parsers.push('hiredis');
125120
protocols.push('IPv6', '/tmp/redis.sock');
126121
}
127-
parsers.forEach(function (parser) {
128-
protocols.forEach(function (ip, i) {
129-
if (i === 0 || options.allConnections) {
130-
cb(parser, ip, config.configureClient(parser, ip));
122+
var options = [{
123+
detect_buffers: true
124+
// Somehow we need a undefined here - otherwise the parsers return_buffers value is always true
125+
// Investigate this further
126+
}, undefined];
127+
options.forEach(function (options) {
128+
var strOptions = '';
129+
var key;
130+
for (key in options) {
131+
if (options.hasOwnProperty(key)) {
132+
strOptions += key + ': ' + options[key] + '; ';
131133
}
134+
}
135+
describe('using options: ' + strOptions, function() {
136+
parsers.forEach(function (parser) {
137+
protocols.forEach(function (ip, i) {
138+
if (i !== 0 && !opts.allConnections) {
139+
return;
140+
}
141+
cb(parser, ip, config.configureClient(parser, ip, options));
142+
});
143+
});
132144
});
133145
});
134146
},

0 commit comments

Comments
 (0)