Skip to content

Commit 2ef2a96

Browse files
committed
Fix the bug that int overflow can bypass the range check
1 parent e8afd05 commit 2ef2a96

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

rxjava-core/src/main/java/rx/Observable.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,15 +2301,18 @@ public static final <K1, K2, T> Observable<GroupedObservable<K2, GroupedObservab
23012301
* the number of sequential Integers to generate
23022302
* @return an Observable that emits a range of sequential Integers
23032303
* @throws IllegalArgumentException
2304-
* if {@code count} is less than zero
2304+
* if {@code count} is less than zero, or if {@code start} + {@code count} - 1 exceeds {@code Integer.MAX_VALUE}
23052305
* @see <a href="https://github.com/Netflix/RxJava/wiki/Creating-Observables#wiki-range">RxJava Wiki: range()</a>
23062306
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229460.aspx">MSDN: Observable.Range</a>
23072307
*/
23082308
public final static Observable<Integer> range(int start, int count) {
23092309
if (count < 0) {
23102310
throw new IllegalArgumentException("Count can not be negative");
23112311
}
2312-
if ((start + count) > Integer.MAX_VALUE) {
2312+
if (count == 0) {
2313+
return Observable.empty();
2314+
}
2315+
if (start > Integer.MAX_VALUE - count + 1) {
23132316
throw new IllegalArgumentException("start + count can not exceed Integer.MAX_VALUE");
23142317
}
23152318
return Observable.create(new OnSubscribeRange(start, start + (count - 1)));

rxjava-core/src/test/java/rx/operators/OnSubscribeRangeTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package rx.operators;
1717

1818
import static org.junit.Assert.assertEquals;
19+
import static org.junit.Assert.assertFalse;
1920
import static org.mockito.Mockito.mock;
2021
import static org.mockito.Mockito.never;
2122
import static org.mockito.Mockito.times;
@@ -67,4 +68,29 @@ public void call(Integer t1) {
6768
verify(observer, times(1)).onCompleted();
6869
assertEquals(3, count.get());
6970
}
71+
72+
@Test
73+
public void testRangeWithOverflow() {
74+
Observable.range(1, 0);
75+
}
76+
77+
@Test
78+
public void testRangeWithOverflow2() {
79+
Observable.range(Integer.MAX_VALUE, 0);
80+
}
81+
82+
@Test
83+
public void testRangeWithOverflow3() {
84+
Observable.range(1, Integer.MAX_VALUE);
85+
}
86+
87+
@Test(expected = IllegalArgumentException.class)
88+
public void testRangeWithOverflow4() {
89+
Observable.range(2, Integer.MAX_VALUE);
90+
}
91+
92+
@Test
93+
public void testRangeWithOverflow5() {
94+
assertFalse(Observable.range(Integer.MIN_VALUE, 0).toBlocking().getIterator().hasNext());
95+
}
7096
}

0 commit comments

Comments
 (0)