From 709b8611af3b64bc6ab6e012c355ef3f1aa1fae6 Mon Sep 17 00:00:00 2001 From: dacoozheng <23788425@qq.com> Date: Sun, 3 Jan 2016 16:23:02 +0800 Subject: [PATCH 1/3] prevent return "undefined" immediately when key is "constructor" for memoize method. --- lib/async.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/async.js b/lib/async.js index 839a66a0c..38da842bb 100644 --- a/lib/async.js +++ b/lib/async.js @@ -1089,12 +1089,12 @@ var memoized = _restParam(function memoized(args) { var callback = args.pop(); var key = hasher.apply(null, args); - if (key in memo) { + if (memo.hasOwnProperty(key)) { async.setImmediate(function () { callback.apply(null, memo[key]); }); } - else if (key in queues) { + else if (queues.hasOwnProperty(key)) { queues[key].push(callback); } else { From 4a6ac52b15f7431e01f6f92a9b03dc2fe36e3b8a Mon Sep 17 00:00:00 2001 From: dacoozheng <23788425@qq.com> Date: Sun, 3 Jan 2016 19:18:43 +0800 Subject: [PATCH 2/3] Test case for #998. --- test/test-async.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/test-async.js b/test/test-async.js index 05c022827..19c30c137 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -4309,6 +4309,32 @@ exports['memoize'] = { test.equal(val, "bar"); test.done(); }); +}, + + 'avoid constructor key return undefined': function (test) { + test.expect(1); + var fn = async.memoize(function(name, callback) { + async.setImmediate(function(){ + callback(null, name); + }); + }); + fn('constructor', function(error, results) { + test.equal(results, 'constructor'); + test.done(); + }); +}, + + 'avoid __proto__ key return undefined': function (test) { + test.expect(1); + var fn = async.memoize(function(name, callback) { + async.setImmediate(function(){ + callback(null, name); + }); + }); + fn('__proto__', function(error, results) { + test.equal(results, '__proto__'); + test.done(); + }); } }; From 16d61f49c88b4c3167a0c592f08216cbd23ade8d Mon Sep 17 00:00:00 2001 From: dacoozheng <23788425@qq.com> Date: Sun, 3 Jan 2016 21:22:14 +0800 Subject: [PATCH 3/3] Allow "hasOwnProperty" as key for memoize method. --- lib/async.js | 5 +++-- test/test-async.js | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/async.js b/lib/async.js index 38da842bb..8cdb9ca57 100644 --- a/lib/async.js +++ b/lib/async.js @@ -1085,16 +1085,17 @@ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; + var has = Object.prototype.hasOwnProperty; hasher = hasher || identity; var memoized = _restParam(function memoized(args) { var callback = args.pop(); var key = hasher.apply(null, args); - if (memo.hasOwnProperty(key)) { + if (has.call(memo, key)) { async.setImmediate(function () { callback.apply(null, memo[key]); }); } - else if (queues.hasOwnProperty(key)) { + else if (has.call(queues, key)) { queues[key].push(callback); } else { diff --git a/test/test-async.js b/test/test-async.js index 19c30c137..e6fe8effd 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -4314,9 +4314,9 @@ exports['memoize'] = { 'avoid constructor key return undefined': function (test) { test.expect(1); var fn = async.memoize(function(name, callback) { - async.setImmediate(function(){ + setTimeout(function(){ callback(null, name); - }); + }, 100); }); fn('constructor', function(error, results) { test.equal(results, 'constructor'); @@ -4327,14 +4327,27 @@ exports['memoize'] = { 'avoid __proto__ key return undefined': function (test) { test.expect(1); var fn = async.memoize(function(name, callback) { - async.setImmediate(function(){ + setTimeout(function(){ callback(null, name); - }); + }, 100); }); fn('__proto__', function(error, results) { test.equal(results, '__proto__'); test.done(); }); +}, + + 'allow hasOwnProperty as key': function (test) { + test.expect(1); + var fn = async.memoize(function(name, callback) { + setTimeout(function(){ + callback(null, name); + }, 100); + }); + fn('hasOwnProperty', function(error, results) { + test.equal(results, 'hasOwnProperty'); + test.done(); + }); } };