Skip to content

Commit 228573b

Browse files
author
Ruben Bridgewater
committed
Support __proto__ and similar as object attribute in hgetall
1 parent a11e0c5 commit 228573b

File tree

4 files changed

+25
-37
lines changed

4 files changed

+25
-37
lines changed

lib/rawObject.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
// Using a predefined object with this prototype is faster than calling `Object.create(null)` directly
4+
// This is needed to make sure `__proto__` and similar reserved words can be used
5+
function RawObject () {}
6+
RawObject.prototype = Object.create(null);
7+
8+
module.exports = RawObject;

lib/utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
'use strict';
22

3+
var RawObject = require('./rawObject');
4+
35
// hgetall converts its replies to an Object. If the reply is empty, null is returned.
46
// These function are only called with internal data and have therefor always the same instanceof X
57
function replyToObject (reply) {
68
// The reply might be a string or a buffer if this is called in a transaction (multi)
79
if (reply.length === 0 || !(reply instanceof Array)) {
810
return null;
911
}
10-
var obj = {};
12+
var obj = new RawObject();
1113
for (var i = 0; i < reply.length; i += 2) {
1214
obj[reply[i].toString('binary')] = reply[i + 1];
1315
}

test/commands/hgetall.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ describe("The 'hgetall' method", function () {
2222
});
2323

2424
it('handles simple keys and values', function (done) {
25-
client.hmset(['hosts', 'mjr', '1', 'another', '23', 'home', '1234'], helper.isString('OK'));
25+
client.hmset(['hosts', '__proto__', '1', 'another', '23', 'home', '1234'], helper.isString('OK'));
2626
client.HGETALL(['hosts'], function (err, obj) {
2727
assert.strictEqual(3, Object.keys(obj).length);
28-
assert.strictEqual('1', obj.mjr.toString());
28+
assert.strictEqual('1', obj.__proto__.toString()); // eslint-disable-line no-proto
2929
assert.strictEqual('23', obj.another.toString());
3030
assert.strictEqual('1234', obj.home.toString());
3131
return done(err);

test/pubsub.spec.js

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -206,49 +206,27 @@ describe('publish/subscribe', function () {
206206
sub.subscribe(channel);
207207
});
208208

209-
it('handles SUBSCRIBE_CLOSE_RESUBSCRIBE', function (done) {
209+
it('subscribe; close; resubscribe with prototype inherited property names', function (done) {
210210
var count = 0;
211-
/* Create two clients. c1 subscribes to two channels, c2 will publish to them.
212-
c2 publishes the first message.
213-
c1 gets the message and drops its connection. It must resubscribe itself.
214-
When it resubscribes, c2 publishes the second message, on the same channel
215-
c1 gets the message and drops its connection. It must resubscribe itself, again.
216-
When it resubscribes, c2 publishes the third message, on the second channel
217-
c1 gets the message and drops its connection. When it reconnects, the test ends.
218-
*/
211+
var channels = ['__proto__', 'channel 2'];
212+
var msg = ['hi from channel __proto__', 'hi from channel 2'];
213+
219214
sub.on('message', function (channel, message) {
220-
if (channel === 'chan1') {
221-
assert.strictEqual(message, 'hi on channel 1');
222-
sub.stream.end();
223-
} else if (channel === 'chan2') {
224-
assert.strictEqual(message, 'hi on channel 2');
225-
sub.stream.end();
226-
} else {
227-
sub.quit();
228-
pub.quit();
229-
assert.fail('test failed');
230-
}
215+
var n = Math.max(count - 1, 0);
216+
assert.strictEqual(channel, channels[n]);
217+
assert.strictEqual(message, msg[n]);
218+
if (count === 2) return done();
219+
sub.stream.end();
231220
});
232221

233-
sub.subscribe('chan1', 'chan2');
222+
sub.subscribe(channels);
234223

235224
sub.on('ready', function (err, results) {
225+
pub.publish(channels[count], msg[count]);
236226
count++;
237-
if (count === 1) {
238-
pub.publish('chan1', 'hi on channel 1');
239-
return;
240-
} else if (count === 2) {
241-
pub.publish('chan2', 'hi on channel 2');
242-
} else {
243-
sub.quit(function () {
244-
pub.quit(function () {
245-
return done();
246-
});
247-
});
248-
}
249227
});
250228

251-
pub.publish('chan1', 'hi on channel 1');
229+
pub.publish(channels[count], msg[count]);
252230
});
253231
});
254232

0 commit comments

Comments
 (0)