Skip to content

Instantly share code, notes, and snippets.

@jacobq
Created December 15, 2018 00:09
Show Gist options
  • Save jacobq/10c5f7e06666aa9de345cca919d64bc0 to your computer and use it in GitHub Desktop.
Save jacobq/10c5f7e06666aa9de345cca919d64bc0 to your computer and use it in GitHub Desktop.
WIP test for EmberJS accidentally creating cyclic structure in Array.prototype
import { NativeArray } from '../../lib/mixins/array';
import { AbstractTestCase, moduleFor } from 'internal-test-helpers';
class ArrayPrototypeExtensionSelfReferenceTests extends AbstractTestCase {
'@test should not create non-Symbol, enumerable properties that refer to itself'() {
// Don't want to pollute Array.prototype so we make our own to extend
class ThrowAwayArray extends Array {}
// Extend our throw-away prototype (like EXTEND_PROTOTYPES.Array would)
NativeArray.apply(ThrowAwayArray.prototype);
// Create an instance to test
let obj = new ThrowAwayArray();
// Home-made depth-first-search for cycle detection
// Alternatively a module from npm (like 'is-circular' could be used instead)
function isCyclic(node, path) {
path = path || [];
path.push(node);
const root = path[0];
for (let p in node) {
const value = node[p];
if (value === root) {
return path.concat(p);
}
else if (typeof value === 'object') {
try {
const result = isCyclic(value, path);
if (result) {
return result;
}
} catch(e) {
return true;
}
}
}
return false;
}
// Make sure that no enumerable properties refer back to the object (creating a cyclic structure)
const result = isCyclic(obj);
this.assert.ok(
result === false,
`Detected a cyclic reference (${result}) on an enumerable part of the prototype.
This is bad because it may break a lot of 3rd party code.
For example, code that explores all properties,
such as jQuery.extend and other "deep cloning" functions,
will get stuck in an infinite loop.
`.replace(/\s+/g, ' ')
);
}
}
moduleFor(`NativeArray: apply`, ArrayPrototypeExtensionSelfReferenceTests);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment