We use some jquery plugins (e.g.: bootstrap-daterangepicker), which uses the extend method from jquery. In v3.6.0-beta.3, this fails as jquery recursively iterates through the [] property of an array (we use the array prototype extensions of Ember)
[email protected]
$.extend(true, {}, {a:['a']}) gives
{a: Array(1)}
[email protected]
$.extend(true, {}, {a:['a']}) gives
jquery.js:282 Uncaught RangeError: Maximum call stack size exceeded
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
at Function.jQuery.extend.jQuery.fn.extend (jquery.js:282)
This is using the same version of jQuery between the two?
I鈥檓 not immediately aware of a change that would have caused this. We will probably need to bisect to track it down...
To reproduce, I created a new project (so no extra dependencies)
ember new extend --yarn
This installs [email protected]
I run the default application and in the browser console I executed the command
$.extend(true, {}, {a:['a']})
Then I upgraded ember
yarn upgrade [email protected]
And this gives the error
JQuery uses for ( name in options ) construct to iterate over the properties.
In ember 3.5.1
Object.getOwnPropertyDescriptor([].__proto__, '[]')
returns
{get: 茠, set: undefined, enumerable: false, configurable: true}
and in ember 3.6.0-beta.3
the result is
{get: 茠, set: undefined, enumerable: true, configurable: true}
As a for...in construct iterates over all enumerable properties, in ember 3.5.1 the [] is not included, but it is included in ember 3.6.0-beta.3
I'm seeing a very similar issue with ember-inputmask:
[Error] RangeError: Maximum call stack size exceeded.
get (vendor.js:28394)
extend (vendor.js:99178)
extend (vendor.js:99190)
extend (vendor.js:99190)
extend (vendor.js:99190)
extend (vendor.js:99190)
....
extend (vendor.js:99190)
Stacktrace shows it's this line of code code which triggers it - which is also a .extend() like the jQuery problem above: https://github.com/RobinHerbots/Inputmask/blob/5.x/lib/dependencyLibs/inputmask.dependencyLib.js#L317
I've tried all beta versions (1-4) and the problem exists in all versions.
As a workaround I execute the following code in an initializer
// TODO: remove once https://github.com/emberjs/ember.js/issues/17190 has been fixed
const properties = ['[]', 'firstObject', 'lastObject', 'hasArrayObservers', '@each'];
properties.forEach(property => {
const desc = Object.getOwnPropertyDescriptor([].__proto__, property);
desc.enumerable = false;
Object.defineProperty([].__proto__, property, desc);
});
This _seems_ like a regression of the fixes in https://github.com/emberjs/ember.js/pull/16169 which was _specifically_ trying to address this issue...
I can confirm that this problem still happens in 3.6 and 3.7.0-beta.1.
One easy way to check for regression is to run for (var x in []) console.log(x):
_super_super, [], firstObject, lastObject hasArrayObservers, and @eachSee also https://github.com/ember-cli/ember-cli/issues/8295
Update: I created a PR to incorporate a test for this, though it doesn't actually fix the problem.
This is using the same version of jQuery between the two?
I鈥檓 not immediately aware of a change that would have caused this. We will probably need to bisect to track it down...
Running git bisect with the test I wrote in #17374 suggests that the problem was introduced by 02af02546a05cd372bf53033318f65af7b544023 246435e7260f45d9e5cc35a4a8b4de4f011f3625
Hmm, that seems somewhat surprising because I think that landed after this issue was reported right?
OK, I am trying again but using more automation (was running the test myself before and may have made a mistake).
Create executable test.sh script with the following contents:
rm -rf dist/ node_modules/
yarn
ember build
node -e "require('./dist/ember.debug.js'); const a = []; for (let p in a) { if (a[p] === a) { throw new Error(\`a[\"\${p}\"] === a\`)}}"
Then bisect like this
git checkout master
git bisect start
git bad
git bisect good v3.5.1
git bisect run ./test.sh
When I ran this just now it finished with:
246435e7260f45d9e5cc35a4a8b4de4f011f3625 is the first bad commit
commit 246435e7260f45d9e5cc35a4a8b4de4f011f3625
Author: bekzod <[email protected]>
Date: Mon Jun 11 21:42:16 2018 +0500
avoid double define for native descriptors
:040000 040000 173ea3396625a0bf0d5ddb72c7591daa93151e33 a4a4903a3f9c3ef40ba3ac9699056005d1b2046c M packages
bisect run success
Awesome, that makes sense!
Now someone just needs to fix it :D
Fixed by #17374
Most helpful comment
Now someone just needs to fix it :D