From 61d1334e5bc422f72ddc7eb5ad259d7b38f3bcdf Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sun, 24 Mar 2019 21:59:20 +0100 Subject: [PATCH] util: increase function length when using `callbackify()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The returned function from `util.callbackify()` should increase the `length` property by one due to the added callback. PR-URL: https://github.com/nodejs/node/pull/26893 Fixes: https://github.com/nodejs/node/issues/26890 Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel Reviewed-By: Michaƫl Zasso --- lib/util.js | 9 +++++++-- test/parallel/test-util-callbackify.js | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/util.js b/lib/util.js index f6f99f82b45..1935955ad28 100644 --- a/lib/util.js +++ b/lib/util.js @@ -195,8 +195,13 @@ function callbackify(original) { } Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original)); - Object.defineProperties(callbackified, - Object.getOwnPropertyDescriptors(original)); + const descriptors = Object.getOwnPropertyDescriptors(original); + // It is possible to manipulate a functions `length` property. This guards + // against the manipulation. + if (typeof descriptors.length.value === 'number') { + descriptors.length.value++; + } + Object.defineProperties(callbackified, descriptors); return callbackified; } diff --git a/test/parallel/test-util-callbackify.js b/test/parallel/test-util-callbackify.js index c381924e1b5..4d7d46658a8 100644 --- a/test/parallel/test-util-callbackify.js +++ b/test/parallel/test-util-callbackify.js @@ -74,6 +74,7 @@ const values = [ } const cbAsyncFn = callbackify(asyncFn); + assert.strictEqual(cbAsyncFn.length, 1); cbAsyncFn(common.mustCall((err, ret) => { assert.strictEqual(ret, undefined); if (err instanceof Error) { @@ -146,6 +147,7 @@ const values = [ } const cbAsyncFn = callbackify(asyncFn); + assert.strictEqual(cbAsyncFn.length, 2); cbAsyncFn(value, common.mustCall((err, ret) => { assert.ifError(err); assert.strictEqual(ret, value); @@ -155,8 +157,16 @@ const values = [ assert.strictEqual(arg, value); return Promise.resolve(arg); } + const obj = {}; + Object.defineProperty(promiseFn, 'length', { + value: obj, + writable: false, + enumerable: false, + configurable: true + }); const cbPromiseFn = callbackify(promiseFn); + assert.strictEqual(promiseFn.length, obj); cbPromiseFn(value, common.mustCall((err, ret) => { assert.ifError(err); assert.strictEqual(ret, value);