Created
December 15, 2018 00:09
-
-
Save jacobq/10c5f7e06666aa9de345cca919d64bc0 to your computer and use it in GitHub Desktop.
WIP test for EmberJS accidentally creating cyclic structure in Array.prototype
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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