Skip to content

Commit

Permalink
Fix the bugs turned up in FuzzedDataProvider fuzz test
Browse files Browse the repository at this point in the history
  • Loading branch information
br-lewis committed Sep 6, 2023
1 parent 7a8d62d commit ed7e7b2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ default<T> T pickValue(Collection<T> collection) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default<T> T pickValue(T[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -319,6 +322,9 @@ default<T> T pickValue(T[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default boolean pickValue(boolean[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -330,6 +336,9 @@ default boolean pickValue(boolean[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default byte pickValue(byte[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -341,6 +350,9 @@ default byte pickValue(byte[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default short pickValue(short[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -352,6 +364,9 @@ default short pickValue(short[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default int pickValue(int[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -363,6 +378,9 @@ default int pickValue(int[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default long pickValue(long[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -374,6 +392,9 @@ default long pickValue(long[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default double pickValue(double[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -385,6 +406,9 @@ default double pickValue(double[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default float pickValue(float[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand All @@ -396,6 +420,9 @@ default float pickValue(float[] array) {
* @return an element from {@code array} chosen based on the fuzzer input
*/
default char pickValue(char[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return array[consumeInt(0, array.length - 1)];
}

Expand Down Expand Up @@ -439,6 +466,9 @@ default<T> List<T> pickValues(Collection<T> collection, int numOfElements) {
* input
*/
default<T> List<T> pickValues(T[] array, int numOfElements) {
if (array.length == 0) {
throw new IllegalArgumentException("array is empty");
}
return pickValues(Arrays.asList(array), numOfElements);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ public long consumeLong(long min, long max) {

@Override
public float consumeRegularFloat(float min, float max) {
if (!Float.isFinite(min)) {
throw new IllegalArgumentException("min must be a regular float");
}
if (!Float.isFinite(max)) {
throw new IllegalArgumentException("max must be a regular float");
}
if (min > max) {
throw new IllegalArgumentException(
String.format("min must be <= max (got min: %f, max: %f)", min, max));
Expand All @@ -209,6 +215,12 @@ public float consumeRegularFloat(float min, float max) {

@Override
public double consumeRegularDouble(double min, double max) {
if (!Double.isFinite(min)) {
throw new IllegalArgumentException("min must be a regular double");
}
if (!Double.isFinite(max)) {
throw new IllegalArgumentException("max must be a regular double");
}
if (min > max) {
throw new IllegalArgumentException(
String.format("min must be <= max (got min: %f, max: %f)", min, max));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,13 @@ ConsumeIntegralArray(JNIEnv &env, jobject self, jint max_length) {
const auto *dataPtr =
reinterpret_cast<const uint8_t *>(env.GetLongField(self, gDataPtrField));
jint remainingBytes = env.GetIntField(self, gRemainingBytesField);
uint64_t requested_bytes = sizeof(T) * max_length;
// requested_bytes may overflow a jint so cap it to remainingBytes which will
// definitely be within jint's range
uint64_t capped_bytes =
std::min(requested_bytes, static_cast<uint64_t>(remainingBytes));

jint max_num_bytes =
std::min(static_cast<jint>(sizeof(T)) * max_length, remainingBytes);
jsize actual_length = max_num_bytes / sizeof(T);
jsize actual_length = static_cast<jint>(capped_bytes) / sizeof(T);
jint actual_num_bytes = sizeof(T) * actual_length;
auto array = (env.*(JniArrayType<T>::kNewArrayFunc))(actual_length);
(env.*(JniArrayType<T>::kSetArrayRegionFunc))(
Expand Down Expand Up @@ -209,7 +212,11 @@ T JNICALL ConsumeFloatInRange(JNIEnv &env, jobject self, T min, T max) {
}

T probability = ConsumeProbability<T>(env, self);
return result + range * probability;
result += range * probability;

// extreme values can cause precision errors that make result > max
// clamp the value to max when that happens
return std::min(result, max);
}

template <typename T>
Expand Down

0 comments on commit ed7e7b2

Please sign in to comment.