diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2021-10-19 11:19:06 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-19 15:29:29 +0200 |
commit | 00f81f770cae3d1b1c936fb14e5727a6e797de95 (patch) | |
tree | cc27d9c6817f1bccd9618a360af8a3fd89fba8fa /agent/src | |
parent | d474119d8e06bc269e37d14287e4b75367f5e130 (diff) | |
download | jazzer-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.java | 33 |
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", |