Skip to content

Commit 6a7a408

Browse files
committed
[GR-51747] Fix possible infinite recursion in AbstractJSObjectArray.setElementImpl (24.0).
PullRequest: js/3043
2 parents 159292d + 5a912d6 commit 6a7a408

File tree

3 files changed

+93
-7
lines changed

3 files changed

+93
-7
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
6+
*/
7+
8+
/**
9+
* Regression test checking successful transition from sealed JSObjectArray to ObjectArray strategy.
10+
*
11+
* @option debug-builtin
12+
*/
13+
14+
load("assert.js");
15+
16+
const o = {};
17+
const x = 42;
18+
19+
for (const jsobjectArrayType of ["ZeroBasedJSObjectArray", "ContiguousJSObjectArray", "HolesJSObjectArray"]) {
20+
const objectArrayType = jsobjectArrayType.replace("JS", "");
21+
switch (jsobjectArrayType) {
22+
case "ZeroBasedJSObjectArray": {
23+
let a = [];
24+
for (let i = 0; i < 8; i++) {
25+
a[i] = o;
26+
}
27+
Object.seal(a);
28+
assertArrayType(a, jsobjectArrayType);
29+
30+
a[5] = x;
31+
32+
assertArrayType(a, objectArrayType);
33+
assertSameContent([o,o,o,o,o,x,o,o], a);
34+
assertTrue(Object.isSealed(a));
35+
break;
36+
}
37+
case "ContiguousJSObjectArray": {
38+
let a = [];
39+
for (let i = 1; i < 8; i++) {
40+
a[i] = o;
41+
}
42+
Object.seal(a);
43+
assertArrayType(a, jsobjectArrayType);
44+
45+
a[0] = x;
46+
assertArrayType(a, jsobjectArrayType);
47+
48+
a[5] = x;
49+
assertArrayType(a, objectArrayType);
50+
assertSameContent([ ,o,o,o,o,x,o,o], a);
51+
assertTrue(Object.isSealed(a));
52+
break;
53+
}
54+
case "HolesJSObjectArray": {
55+
let a = [];
56+
for (let i = 0; i < 8; i++) {
57+
if (i == 4) {
58+
continue;
59+
}
60+
a[i] = o;
61+
}
62+
Object.seal(a);
63+
assertArrayType(a, jsobjectArrayType);
64+
65+
a[4] = x;
66+
assertArrayType(a, jsobjectArrayType);
67+
a[5] = x;
68+
69+
assertArrayType(a, objectArrayType);
70+
assertSameContent([o,o,o,o, ,x,o,o], a);
71+
assertTrue(Object.isSealed(a));
72+
break;
73+
}
74+
default: throw new TypeError(jsobjectArrayType);
75+
}
76+
}
77+
78+
function assertArrayType(array, expected) {
79+
assertSame(expected, Debug.arraytype(array))
80+
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/interop/ArrayElementInfoNode.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -49,6 +49,7 @@
4949
import com.oracle.truffle.js.nodes.JavaScriptBaseNode;
5050
import com.oracle.truffle.js.runtime.JSRuntime;
5151
import com.oracle.truffle.js.runtime.array.ScriptArray;
52+
import com.oracle.truffle.js.runtime.builtins.JSAbstractArray;
5253
import com.oracle.truffle.js.runtime.builtins.JSArrayBase;
5354

5455
/**
@@ -99,7 +100,7 @@ static TriState doCached(JSArrayBase target, long index, int query,
99100
return TriState.UNDEFINED;
100101
}
101102
}
102-
if (index >= 0 && index < arrayType.length(target)) {
103+
if (index >= 0 && index < JSAbstractArray.arrayGetLength(target)) {
103104
if ((query & READABLE) != 0) {
104105
return TriState.TRUE;
105106
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/array/dyn/AbstractJSObjectArray.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -78,10 +78,15 @@ public final ScriptArray setElementImpl(JSDynamicObject object, long index, Obje
7878
}
7979

8080
private ScriptArray rewrite(JSDynamicObject object, long index, Object value) {
81-
if (isSupportedContiguous(object, index)) {
82-
return toContiguous(object, index, value);
83-
} else if (isSupportedHoles(object, index)) {
84-
return toHoles(object, index, value);
81+
if (JSDynamicObject.isJSDynamicObject(value)) {
82+
assert !isSupported(object, index);
83+
if (isSupportedContiguous(object, index)) {
84+
return toContiguous(object, index, value);
85+
} else if (isSupportedHoles(object, index)) {
86+
return toHoles(object, index, value);
87+
} else {
88+
return toSparse(object, index, value);
89+
}
8590
} else {
8691
return toObject(object, index, value);
8792
}

0 commit comments

Comments
 (0)