1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// Copyright (C) 2017 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-array.prototype.splice
description: >
Create species constructor with length exceeding integer limit and ensure MOP
operations are called in correct order.
info: |
...
9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
10. Let k be 0.
11. Repeat, while k < actualDeleteCount
a. Let from be ! ToString(actualStart+k).
b. Let fromPresent be ? HasProperty(O, from).
c. If fromPresent is true, then
i. Let fromValue be ? Get(O, from).
ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(k), fromValue).
d. Increment k by 1.
12. Perform ? Set(A, "length", actualDeleteCount, true).
...
includes: [compareArray.js, proxyTrapsHelper.js]
features: [Symbol.species, exponentiation]
---*/
function StopSplice() {}
var traps = [];
var targetLength;
var array = ["no-hole", /* hole */ , "stop"];
array.constructor = {
[Symbol.species]: function(n) {
targetLength = n;
return target;
}
};
var source = new Proxy(array, allowProxyTraps({
get(t, pk, r) {
traps.push(`source.[[Get]]:${String(pk)}`);
// length property exceeding 2^53-1.
if (pk === "length")
return 2 ** 53 + 2;
return Reflect.get(t, pk, r);
},
has(t, pk, r) {
traps.push(`source.[[Has]]:${String(pk)}`);
return Reflect.get(t, pk, r);
},
}));
var target = new Proxy([], allowProxyTraps({
defineProperty(t, pk, desc) {
traps.push(`target.[[DefineProperty]]:${String(pk)}`);
if (pk === "0" || pk === "1")
return Reflect.defineProperty(t, pk, desc);
throw new StopSplice();
}
}));
assert.throws(StopSplice, function() {
// deleteCount argument exceeding 2^53-1.
Array.prototype.splice.call(source, 0, 2 ** 53 + 4);
}, '// deleteCount argument exceeding 2^53-1. Array.prototype.splice.call(source, 0, 2 ** 53 + 4) throws a StopSplice exception');
assert.sameValue(targetLength, 2 ** 53 - 1,
'The value of targetLength is expected to be 2 ** 53 - 1');
assert.compareArray(traps, [
"source.[[Get]]:length",
"source.[[Get]]:constructor",
"source.[[Has]]:0",
"source.[[Get]]:0",
"target.[[DefineProperty]]:0",
"source.[[Has]]:1",
"source.[[Has]]:2",
"source.[[Get]]:2",
"target.[[DefineProperty]]:2",
], 'The value of traps is expected to be [\n "source.[[Get]]:length",\n\n "source.[[Get]]:constructor",\n\n "source.[[Has]]:0",\n "source.[[Get]]:0",\n "target.[[DefineProperty]]:0",\n\n "source.[[Has]]:1",\n\n "source.[[Has]]:2",\n "source.[[Get]]:2",\n "target.[[DefineProperty]]:2",\n]');
reportCompare(0, 0);
|