Skip to content

Commit 3828dc9

Browse files
nikita-sakharinshipilev
authored andcommitted
8314236: Overflow in Collections.rotate
Co-authored-by: Nikita Sakharin <17588081+nikita-sakharin@users.noreply.github.com> Reviewed-by: shade, smarks
1 parent 1203e11 commit 3828dc9

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

src/java.base/share/classes/java/util/Collections.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -816,15 +816,16 @@ private static <T> void rotate1(List<T> list, int distance) {
816816
if (distance == 0)
817817
return;
818818

819-
for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
819+
int bound = size - distance;
820+
for (int cycleStart = 0, nMoved = 0; nMoved < size; cycleStart++) {
820821
T displaced = list.get(cycleStart);
821822
int i = cycleStart;
822823
do {
823-
i += distance;
824-
if (i >= size)
824+
if (i >= bound)
825825
i -= size;
826+
i += distance;
826827
displaced = list.set(i, displaced);
827-
nMoved ++;
828+
nMoved++;
828829
} while (i != cycleStart);
829830
}
830831
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8314236
27+
* @summary Overflow in Collections.rotate
28+
*/
29+
30+
import java.util.AbstractList;
31+
import java.util.Collections;
32+
import java.util.List;
33+
import java.util.Objects;
34+
import java.util.RandomAccess;
35+
36+
public class RotateHuge {
37+
38+
private static final class MockList extends AbstractList<Object>
39+
implements RandomAccess {
40+
private final int size;
41+
42+
public MockList(final int size) {
43+
if (size < 0)
44+
throw new IllegalArgumentException("Illegal size: " + size);
45+
this.size = size;
46+
}
47+
48+
@Override
49+
public Object get(final int index) {
50+
Objects.checkIndex(index, size);
51+
return null;
52+
}
53+
54+
@Override
55+
public Object set(final int index, final Object element) {
56+
Objects.checkIndex(index, size);
57+
return null;
58+
}
59+
60+
@Override
61+
public int size() {
62+
return size;
63+
}
64+
}
65+
66+
public static void main(final String[] args) {
67+
testRotate((1 << 30) + 1, -(1 << 30) - 2);
68+
testRotate((1 << 30) + 1, 1 << 30);
69+
testRotate(Integer.MAX_VALUE, Integer.MIN_VALUE);
70+
testRotate(Integer.MAX_VALUE, Integer.MIN_VALUE + 3);
71+
testRotate(Integer.MAX_VALUE, 2);
72+
testRotate(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
73+
}
74+
75+
/*
76+
* This test covers only index computations.
77+
* Correctness of elements rotation is not checked.
78+
*/
79+
private static void testRotate(final int size, final int distance) {
80+
final List<Object> list = new MockList(size);
81+
Collections.rotate(list, distance);
82+
}
83+
}

0 commit comments

Comments
 (0)