Explicit checks for positive (big) array length

This commit is contained in:
Sebastiano Vigna 2022-10-02 14:17:11 +02:00
parent e39878edc2
commit ac10cae36e
2 changed files with 23 additions and 11 deletions

View file

@ -317,7 +317,7 @@ public class BigArrays {
* This method may be used whenever a big array range check is needed.
*
* @param bigArrayLength
* a big-array length.
* a big-array length (must be nonnegative).
* @param from
* a start index (inclusive).
* @param to
@ -327,8 +327,11 @@ public class BigArrays {
* @throws ArrayIndexOutOfBoundsException
* if {@code from} or {@code to} are greater than
* {@code bigArrayLength} or negative.
*
* @implNote An {@code assert} checks whether {@code bigArrayLength} is nonnegative.
*/
public static void ensureFromTo(final long bigArrayLength, final long from, final long to) {
assert bigArrayLength >= 0;
if (from < 0) throw new ArrayIndexOutOfBoundsException("Start index (" + from + ") is negative");
if (from > to) throw new IllegalArgumentException("Start index (" + from + ") is greater than end index (" + to + ")");
if (to > bigArrayLength) throw new ArrayIndexOutOfBoundsException("End index (" + to + ") is greater than big-array length (" + bigArrayLength + ")");
@ -342,7 +345,7 @@ public class BigArrays {
* This method may be used whenever a big array range check is needed.
*
* @param bigArrayLength
* a big-array length.
* a big-array length (must be nonnegative).
* @param offset
* a start index for the fragment
* @param length
@ -353,11 +356,14 @@ public class BigArrays {
* if {@code offset} is negative or {@code offset} +
* {@code length} is greater than
* {@code bigArrayLength}.
*
* @implNote An {@code assert} checks whether {@code bigArrayLength} is nonnegative.
*/
public static void ensureOffsetLength(final long bigArrayLength, final long offset, final long length) {
assert bigArrayLength >= 0;
if (offset < 0) throw new ArrayIndexOutOfBoundsException("Offset (" + offset + ") is negative");
if (length < 0) throw new IllegalArgumentException("Length (" + length + ") is negative");
if (Long.compareUnsigned(offset + length, bigArrayLength) > 0) throw new ArrayIndexOutOfBoundsException("Last index (" + Long.toUnsignedString(offset + length) + ") is greater than big-array length (" + bigArrayLength + ")");
if (length > bigArrayLength - offset) throw new ArrayIndexOutOfBoundsException("Last index (" + Long.toUnsignedString(offset + length) + ") is greater than big-array length (" + bigArrayLength + ")");
}
/**

View file

@ -49,25 +49,28 @@ public class Arrays {
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Ensures that a range given by its first (inclusive) and last (exclusive) elements fits an
* array of given length.
* Ensures that a range given by its first (inclusive) and last (exclusive) elements fits an array
* of given length.
*
* <p>
* This method may be used whenever an array range check is needed.
*
* <p>
* In Java 9 and up, this method should be considered deprecated in favor of the
* {@link java.util.Objects#checkFromToIndex(int, int, int)} method, which may be intrinsified
* in recent JVMs.
* {@link java.util.Objects#checkFromToIndex(int, int, int)} method, which may be intrinsified in
* recent JVMs.
*
* @param arrayLength an array length.
* @param arrayLength an array length (must be nonnegative).
* @param from a start index (inclusive).
* @param to an end index (inclusive).
* @throws IllegalArgumentException if {@code from} is greater than {@code to}.
* @throws ArrayIndexOutOfBoundsException if {@code from} or {@code to} are greater than
* {@code arrayLength} or negative.
*
* @implNote An {@code assert} checks whether {@code arrayLength} is nonnegative.
*/
public static void ensureFromTo(final int arrayLength, final int from, final int to) {
assert arrayLength >= 0;
// When Java 9 becomes the minimum, use Objects#checkFromToIndex, as that can be an intrinsic
if (from < 0) throw new ArrayIndexOutOfBoundsException("Start index (" + from + ") is negative");
if (from > to) throw new IllegalArgumentException("Start index (" + from + ") is greater than end index (" + to + ")");
@ -82,17 +85,20 @@ public class Arrays {
*
* <p>
* In Java 9 and up, this method should be considered deprecated in favor of the
* {@link java.util.Objects#checkFromIndexSize(int, int, int)} method, which may be intrinsified
* in recent JVMs.
* {@link java.util.Objects#checkFromIndexSize(int, int, int)} method, which may be intrinsified in
* recent JVMs.
*
* @param arrayLength an array length.
* @param arrayLength an array length (must be nonnegative).
* @param offset a start index for the fragment
* @param length a length (the number of elements in the fragment).
* @throws IllegalArgumentException if {@code length} is negative.
* @throws ArrayIndexOutOfBoundsException if {@code offset} is negative or
* {@code offset}+{@code length} is greater than {@code arrayLength}.
*
* @implNote An {@code assert} checks whether {@code arrayLength} is nonnegative.
*/
public static void ensureOffsetLength(final int arrayLength, final int offset, final int length) {
assert arrayLength >= 0;
// When Java 9 becomes the minimum, use Objects#checkFromIndexSize, as that can be an intrinsic
if (offset < 0) throw new ArrayIndexOutOfBoundsException("Offset (" + offset + ") is negative");
if (length < 0) throw new IllegalArgumentException("Length (" + length + ") is negative");