aboutsummaryrefslogtreecommitdiff
path: root/agent/src
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-10-19 11:19:06 +0200
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-10-19 15:29:29 +0200
commit00f81f770cae3d1b1c936fb14e5727a6e797de95 (patch)
treecc27d9c6817f1bccd9618a360af8a3fd89fba8fa /agent/src
parentd474119d8e06bc269e37d14287e4b75367f5e130 (diff)
downloadjazzer-api-00f81f770cae3d1b1c936fb14e5727a6e797de95.tar.gz
Improve Autofuzz' fuzzer byte budget handling
Before determining the length of an array to be created in consume, compute or estimate the number of bytes required to create a single object of the component type.
Diffstat (limited to 'agent/src')
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java33
1 files changed, 25 insertions, 8 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java
index 1f35c0a4..ad439730 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java
@@ -120,22 +120,32 @@ public class Meta {
return null;
}
if (type == String.class || type == CharSequence.class) {
- return data.consumeString(data.remainingBytes() / 2);
+ return data.consumeString(consumeArrayLength(data, 1));
} else if (type.isArray()) {
if (type == byte[].class) {
- return data.consumeBytes(data.remainingBytes() / 2);
+ return data.consumeBytes(consumeArrayLength(data, Byte.BYTES));
} else if (type == int[].class) {
- return data.consumeInts(data.remainingBytes() / 2);
+ return data.consumeInts(consumeArrayLength(data, Integer.BYTES));
} else if (type == short[].class) {
- return data.consumeShorts(data.remainingBytes() / 2);
+ return data.consumeShorts(consumeArrayLength(data, Short.BYTES));
} else if (type == long[].class) {
- return data.consumeLongs(data.remainingBytes() / 2);
+ return data.consumeLongs(consumeArrayLength(data, Long.BYTES));
} else if (type == boolean[].class) {
- return data.consumeBooleans(data.remainingBytes() / 2);
+ return data.consumeBooleans(consumeArrayLength(data, 1));
} else {
- Object array = Array.newInstance(type.getComponentType(), data.remainingBytes() / 2);
+ int remainingBytesBeforeFirstElementCreation = data.remainingBytes();
+ Object firstElement = consume(data, type.getComponentType());
+ int remainingBytesAfterFirstElementCreation = data.remainingBytes();
+ int sizeOfElementEstimate =
+ remainingBytesBeforeFirstElementCreation - remainingBytesAfterFirstElementCreation;
+ Object array = Array.newInstance(
+ type.getComponentType(), consumeArrayLength(data, sizeOfElementEstimate));
for (int i = 0; i < Array.getLength(array); i++) {
- Array.set(array, i, consume(data, type.getComponentType()));
+ if (i == 0) {
+ Array.set(array, i, firstElement);
+ } else {
+ Array.set(array, i, consume(data, type.getComponentType()));
+ }
}
return array;
}
@@ -248,6 +258,13 @@ public class Meta {
return value != null && !value.isEmpty();
}
+ private static int consumeArrayLength(FuzzedDataProvider data, int sizeOfElement) {
+ // Spend at most half of the fuzzer input bytes so that the remaining arguments that require
+ // construction still have non-trivial data to work with.
+ int bytesToSpend = data.remainingBytes() / 2;
+ return bytesToSpend / Math.max(sizeOfElement, 1);
+ }
+
private static String getDebugSummary(
Executable executable, Object thisObject, Object[] arguments) {
return String.format("%nMethod: %s::%s%s%nthis: %s%nArguments: %s",