| function shouldThrowStackOverflow(f) { |
| let threw = false; |
| const verbose = false; |
| try { |
| f(); |
| } catch(e) { |
| threw = e instanceof RangeError; |
| } |
| if (!threw) |
| throw new Error("No stack overflow error thrown."); |
| if (verbose) |
| print("passed test: " + f + "\n\n"); |
| } |
| |
| const emptyFunction = function() { }; |
| let seenStartObjects = new Map; |
| function makeLongProxyChain(startObject = emptyFunction) { |
| if (seenStartObjects.has(startObject)) |
| return seenStartObjects.get(startObject); |
| |
| let p = new Proxy(startObject, { }); |
| for (let i = 0; i < 500000; i++) |
| p = new Proxy(p, {}); |
| seenStartObjects.set(startObject, p); |
| return p; |
| } |
| |
| shouldThrowStackOverflow(function longProxyChain() { |
| let f = makeLongProxyChain(); |
| f.name; |
| }); |
| |
| shouldThrowStackOverflow(function effecivelyCyclicProxyProtoChain1() { |
| let t = {}; |
| let p = new Proxy(t, {}); |
| Object.setPrototypeOf(t, p); |
| t.propertyDoesNotExist; |
| }); |
| |
| shouldThrowStackOverflow(function effecivelyCyclicProxyProtoChain2() { |
| let t = {}; |
| let p = new Proxy(t, {}); |
| Object.setPrototypeOf(t, p); |
| for (var k in p) |
| break; |
| }); |
| |
| shouldThrowStackOverflow(function effecivelyCyclicProxyProtoChain3() { |
| let t = {}; |
| let p = new Proxy(t, {}); |
| Object.setPrototypeOf(t, p); |
| Object.prototype.toString.call(p); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainBind() { |
| let p = makeLongProxyChain(); |
| Function.prototype.bind.call(p) |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainPropertyAccess() { |
| let p = makeLongProxyChain(); |
| p.nonExistentProperty; |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainReflectConstruct() { |
| let p = makeLongProxyChain(); |
| Reflect.construct(Array, [], p); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainReflectSet() { |
| let p = makeLongProxyChain(); |
| Reflect.set([null], 0, 0, p); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainReflectOwnKeys() { |
| let p = makeLongProxyChain(); |
| Reflect.ownKeys(p); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainGetPrototypeOf() { |
| let p = makeLongProxyChain(); |
| Reflect.getPrototypeOf(p); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainSetPrototypeOf() { |
| let p = makeLongProxyChain(); |
| Reflect.setPrototypeOf(p, null); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainGetOwnPropertyDescriptor() { |
| let p = makeLongProxyChain(); |
| Reflect.getOwnPropertyDescriptor(p, ""); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainDefineProperty() { |
| let p = makeLongProxyChain(); |
| Reflect.defineProperty(p, "", {}); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainIsExtensible() { |
| let p = makeLongProxyChain(); |
| Reflect.isExtensible(p); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainPreventExtensions() { |
| let p = makeLongProxyChain(); |
| Reflect.preventExtensions(p) |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainDeleteProperty() { |
| let p = makeLongProxyChain(); |
| Reflect.deleteProperty(p, ""); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainWithScope() { |
| let p = makeLongProxyChain(); |
| with (p) { |
| propertyLookup; |
| } |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainWithScope2() { |
| let p = makeLongProxyChain(); |
| with (p) { |
| storeToProperty = 0; |
| } |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainWithScope3() { |
| let p = makeLongProxyChain(); |
| with (p) { |
| someFunctionPropertyLookup() |
| } |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainArrayPrototypePush() { |
| let p = makeLongProxyChain(); |
| Array.prototype.push.call(p, 0); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainWithScope4() { |
| let p = makeLongProxyChain(); |
| with (p) { |
| eval(""); |
| } |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainCall() { |
| let p = makeLongProxyChain(); |
| p(); |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainConstruct() { |
| let p = makeLongProxyChain(); |
| new p; |
| }); |
| |
| shouldThrowStackOverflow(function longProxyChainHas() { |
| let p = makeLongProxyChain(); |
| Reflect.has(p, "foo"); |
| }); |