From c8b885dd3e35632df407df4bd463d9a5cc90280b Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Tue, 16 Nov 2021 03:09:43 +0200 Subject: [PATCH] Prevent proxying CanvasGradient in Node platform (#9861) --- src/helpers/helpers.config.js | 5 +++-- test/specs/helpers.config.tests.js | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/helpers/helpers.config.js b/src/helpers/helpers.config.js index f59ed31f6eb..4d27f9e5b02 100644 --- a/src/helpers/helpers.config.js +++ b/src/helpers/helpers.config.js @@ -178,7 +178,8 @@ export function _descriptors(proxy, defaults = {scriptable: true, indexable: tru } const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name; -const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters'; +const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters' && + (Object.getPrototypeOf(value) === null || value.constructor === Object); function _cached(target, prop, resolve) { if (Object.prototype.hasOwnProperty.call(target, prop)) { @@ -218,7 +219,7 @@ function _resolveScriptable(prop, value, target, receiver) { _stack.add(prop); value = value(_context, _subProxy || receiver); _stack.delete(prop); - if (isObject(value)) { + if (needsSubResolver(prop, value)) { // When scriptable option returns an object, create a resolver on that. value = createSubResolver(_proxy._scopes, _proxy, prop, value); } diff --git a/test/specs/helpers.config.tests.js b/test/specs/helpers.config.tests.js index 811d386d303..58e295b580b 100644 --- a/test/specs/helpers.config.tests.js +++ b/test/specs/helpers.config.tests.js @@ -752,6 +752,29 @@ describe('Chart.helpers.config', function() { expect(fn()).toEqual('ok'); }); + it('should not create proxy for objects with custom constructor', function() { + class MyClass { + constructor() { + this.string = 'test string'; + } + method(arg) { + return arg === undefined ? 'ok' : 'fail'; + } + } + + const defaults = { + test: new MyClass() + }; + + const resolver = _createResolver([{}, defaults]); + const opts = _attachContext(resolver, {index: 1}); + const fn = opts.test.method; + expect(typeof fn).toBe('function'); + expect(fn()).toEqual('ok'); + expect(opts.test.string).toEqual('test string'); + expect(opts.test.constructor).toEqual(MyClass); + }); + it('should properly set value to object in array of objects', function() { const defaults = {}; const options = {