From bc58e89fac9cd2524627f8b4b324131e9f79e8cc Mon Sep 17 00:00:00 2001 From: dead-horse Date: Thu, 18 Jun 2020 01:12:45 +0800 Subject: [PATCH 1/4] fix: remove invalid function name --- index.js | 6 +++++- test/test.js | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 161d32e..312a7d3 100644 --- a/index.js +++ b/index.js @@ -54,6 +54,9 @@ function createCallback(resolve, reject, multiArgs) { function createWrapper(name, options) { name = (name || '').replace(/\s|bound(?!$)/g, '') + // avoid atack by invalid function name + if (name && !/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/.test(name)) name = ''; + options = options || {} // default to true var multiArgs = options.multiArgs !== undefined ? options.multiArgs : true @@ -64,7 +67,7 @@ function createWrapper(name, options) { + 'if (lastType === "function") return $$__fn__$$.apply(self, arguments)\n' : '' - return '(function ' + name + '() {\n' + const res = '(function ' + name + '() {\n' + 'var self = this\n' + 'var len = arguments.length\n' + multiArgs @@ -77,4 +80,5 @@ function createWrapper(name, options) { + '$$__fn__$$.apply(self, args)\n' + '})\n' + '})' + return res } diff --git a/test/test.js b/test/test.js index 930816b..430e07d 100644 --- a/test/test.js +++ b/test/test.js @@ -69,3 +69,27 @@ it('fn(..args, callback())', function () { assert.deepEqual(values, [1, 2, 3]) }) }) + +it('unicode function name', function () { + function 你好$hello_123(a, b, c, cb) { + cb(null, a, b, c) + } + var wrapper = thenify(你好$hello_123) + assert.equal(wrapper.name, '你好$hello_123') + wrapper(1, 2, 3).then(function (values) { + assert.deepEqual(values, [1, 2, 3]) + }) +}) + +it('invalid function name', function () { + function fn(a, b, c, cb) { + cb(null, a, b, c) + } + + Object.defineProperty(fn, 'name', { value: 'fake() {a.b;})();(function(){//' }) + var wrapper = thenify(fn) + assert.equal(wrapper.name, '') + wrapper(1, 2, 3).then(function (values) { + assert.deepEqual(values, [1, 2, 3]) + }) +}) From ea8bedb40ca1315dc4ad8a16c18e776a71be0f41 Mon Sep 17 00:00:00 2001 From: dead-horse Date: Thu, 18 Jun 2020 01:13:47 +0800 Subject: [PATCH 2/4] f --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 312a7d3..50c4fb2 100644 --- a/index.js +++ b/index.js @@ -67,7 +67,7 @@ function createWrapper(name, options) { + 'if (lastType === "function") return $$__fn__$$.apply(self, arguments)\n' : '' - const res = '(function ' + name + '() {\n' + return '(function ' + name + '() {\n' + 'var self = this\n' + 'var len = arguments.length\n' + multiArgs @@ -80,5 +80,4 @@ function createWrapper(name, options) { + '$$__fn__$$.apply(self, args)\n' + '})\n' + '})' - return res } From fadc8f0c1e38bdc62d7df6a954839a2a2abb5427 Mon Sep 17 00:00:00 2001 From: dead-horse Date: Thu, 18 Jun 2020 01:23:36 +0800 Subject: [PATCH 3/4] f --- index.js | 54 +++++++++++++++++++++++----------------------------- test/test.js | 4 ++-- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/index.js b/index.js index 50c4fb2..2b054ab 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,7 @@ module.exports = thenify function thenify($$__fn__$$, options) { assert(typeof $$__fn__$$ === 'function') - return eval(createWrapper($$__fn__$$.name, options)) + return createWrapper($$__fn__$$, options) } /** @@ -29,11 +29,12 @@ thenify.withCallback = function ($$__fn__$$, options) { assert(typeof $$__fn__$$ === 'function') options = options || {} options.withCallback = true - if (options.multiArgs === undefined) options.multiArgs = true - return eval(createWrapper($$__fn__$$.name, options)) + return createWrapper($$__fn__$$, options) } function createCallback(resolve, reject, multiArgs) { + // default to true + if (multiArgs === undefined) multiArgs = true return function(err, value) { if (err) return reject(err) var length = arguments.length @@ -52,32 +53,25 @@ function createCallback(resolve, reject, multiArgs) { } } -function createWrapper(name, options) { - name = (name || '').replace(/\s|bound(?!$)/g, '') - // avoid atack by invalid function name - if (name && !/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/.test(name)) name = ''; - +function createWrapper(fn, options) { options = options || {} - // default to true - var multiArgs = options.multiArgs !== undefined ? options.multiArgs : true - multiArgs = 'var multiArgs = ' + JSON.stringify(multiArgs) + '\n' - - var withCallback = options.withCallback ? - 'var lastType = typeof arguments[len - 1]\n' - + 'if (lastType === "function") return $$__fn__$$.apply(self, arguments)\n' - : '' - - return '(function ' + name + '() {\n' - + 'var self = this\n' - + 'var len = arguments.length\n' - + multiArgs - + withCallback - + 'var args = new Array(len + 1)\n' - + 'for (var i = 0; i < len; ++i) args[i] = arguments[i]\n' - + 'var lastIndex = i\n' - + 'return new Promise(function (resolve, reject) {\n' - + 'args[lastIndex] = createCallback(resolve, reject, multiArgs)\n' - + '$$__fn__$$.apply(self, args)\n' - + '})\n' - + '})' + var name = fn.name; + name = (name || '').replace(/\s|bound(?!$)/g, '') + var newFn = function () { + var self = this + var len = arguments.length + if (options.withCallback) { + var lastType = typeof arguments[len - 1] + if (lastType === 'function') return fn.apply(self, arguments) + } + var args = new Array(len + 1) + for (var i = 0; i < len; ++i) args[i] = arguments[i] + var lastIndex = i + return new Promise(function (resolve, reject) { + args[lastIndex] = createCallback(resolve, reject, options.multiArgs) + fn.apply(self, args) + }) + } + Object.defineProperty(newFn, 'name', { value: name }); + return newFn; } diff --git a/test/test.js b/test/test.js index 430e07d..38d4a84 100644 --- a/test/test.js +++ b/test/test.js @@ -86,9 +86,9 @@ it('invalid function name', function () { cb(null, a, b, c) } - Object.defineProperty(fn, 'name', { value: 'fake() {a.b;})();(function(){//' }) + Object.defineProperty(fn, 'name', { value: 'fake(){a.b;})();(function(){//' }) var wrapper = thenify(fn) - assert.equal(wrapper.name, '') + assert.equal(wrapper.name, fn.name) wrapper(1, 2, 3).then(function (values) { assert.deepEqual(values, [1, 2, 3]) }) From 602061aa6064b0a197e9c2979188ed2eb0665f80 Mon Sep 17 00:00:00 2001 From: dead-horse Date: Thu, 18 Jun 2020 01:25:16 +0800 Subject: [PATCH 4/4] f --- index.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 2b054ab..d633174 100644 --- a/index.js +++ b/index.js @@ -7,29 +7,29 @@ module.exports = thenify /** * Turn async functions into promises * - * @param {Function} $$__fn__$$ + * @param {Function} fn * @return {Function} * @api public */ -function thenify($$__fn__$$, options) { - assert(typeof $$__fn__$$ === 'function') - return createWrapper($$__fn__$$, options) +function thenify(fn, options) { + assert(typeof fn === 'function') + return createWrapper(fn, options) } /** * Turn async functions into promises and backward compatible with callback * - * @param {Function} $$__fn__$$ + * @param {Function} fn * @return {Function} * @api public */ -thenify.withCallback = function ($$__fn__$$, options) { - assert(typeof $$__fn__$$ === 'function') +thenify.withCallback = function (fn, options) { + assert(typeof fn === 'function') options = options || {} options.withCallback = true - return createWrapper($$__fn__$$, options) + return createWrapper(fn, options) } function createCallback(resolve, reject, multiArgs) { @@ -72,6 +72,6 @@ function createWrapper(fn, options) { fn.apply(self, args) }) } - Object.defineProperty(newFn, 'name', { value: name }); - return newFn; + Object.defineProperty(newFn, 'name', { value: name }) + return newFn }