diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2021-10-21 14:02:07 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-21 15:49:56 +0200 |
commit | 71940af7a9c57d00f6a5ec3a9e510d2f47c014e6 (patch) | |
tree | 027b55f26923da3155c6ad797ac66db3e0e2b0b0 /agent | |
parent | 2d8947f3e408a7e2a79d3b8965cfd19390f03a08 (diff) | |
download | jazzer-api-71940af7a9c57d00f6a5ec3a9e510d2f47c014e6.tar.gz |
Add Jazzer.autofuzz(FuzzedDataProvider, Consumer{1,2,3,4,5}) to the API
Also add a test to catch potential copy&paste issues.
Diffstat (limited to 'agent')
-rw-r--r-- | agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java | 142 | ||||
-rw-r--r-- | agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java | 30 |
2 files changed, 172 insertions, 0 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java b/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java index 0a22cc36..e45f7600 100644 --- a/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java +++ b/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java @@ -35,6 +35,11 @@ final public class Jazzer { private static MethodHandle autofuzzFunction3 = null; private static MethodHandle autofuzzFunction4 = null; private static MethodHandle autofuzzFunction5 = null; + private static MethodHandle autofuzzConsumer1 = null; + private static MethodHandle autofuzzConsumer2 = null; + private static MethodHandle autofuzzConsumer3 = null; + private static MethodHandle autofuzzConsumer4 = null; + private static MethodHandle autofuzzConsumer5 = null; static { try { @@ -71,6 +76,16 @@ final public class Jazzer { MethodType.methodType(Object.class, FuzzedDataProvider.class, Function4.class)); autofuzzFunction5 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", MethodType.methodType(Object.class, FuzzedDataProvider.class, Function5.class)); + autofuzzConsumer1 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", + MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer1.class)); + autofuzzConsumer2 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", + MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer2.class)); + autofuzzConsumer3 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", + MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer3.class)); + autofuzzConsumer4 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", + MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer4.class)); + autofuzzConsumer5 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", + MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer5.class)); } catch (ClassNotFoundException ignore) { // Not running in the context of the agent. This is fine as long as no methods are called on // this class. @@ -238,6 +253,133 @@ final public class Jazzer { } /** + * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input + * using only public methods available on the classpath. + * + * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in + * meaningful ways for a number of reasons. + * + * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}. + * @param func a method reference for the function to autofuzz. If there are multiple overloads, + * resolve ambiguities by explicitly casting to {@link Consumer1} with explicitly specified + * type variable. + * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link + * AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call. + * The {@link Throwable} is thrown unchecked. + */ + public static <T1> void autofuzz(FuzzedDataProvider data, Consumer1<T1> func) { + try { + autofuzzConsumer1.invoke(data, func); + } catch (AutofuzzInvocationException e) { + rethrowUnchecked(e.getCause()); + } catch (Throwable t) { + rethrowUnchecked(t); + } + } + + /** + * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input + * using only public methods available on the classpath. + * + * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in + * meaningful ways for a number of reasons. + * + * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}. + * @param func a method reference for the function to autofuzz. If there are multiple overloads, + * resolve ambiguities by explicitly casting to {@link Consumer2} with (partially) specified + * type variables. + * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link + * AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call. + * The {@link Throwable} is thrown unchecked. + */ + public static <T1, T2> void autofuzz(FuzzedDataProvider data, Consumer2<T1, T2> func) { + try { + autofuzzConsumer2.invoke(data, func); + } catch (AutofuzzInvocationException e) { + rethrowUnchecked(e.getCause()); + } catch (Throwable t) { + rethrowUnchecked(t); + } + } + + /** + * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input + * using only public methods available on the classpath. + * + * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in + * meaningful ways for a number of reasons. + * + * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}. + * @param func a method reference for the function to autofuzz. If there are multiple overloads, + * resolve ambiguities by explicitly casting to {@link Consumer3} with (partially) specified + * type variables. + * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link + * AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call. + * The {@link Throwable} is thrown unchecked. + */ + public static <T1, T2, T3> void autofuzz(FuzzedDataProvider data, Consumer3<T1, T2, T3> func) { + try { + autofuzzConsumer3.invoke(data, func); + } catch (AutofuzzInvocationException e) { + rethrowUnchecked(e.getCause()); + } catch (Throwable t) { + rethrowUnchecked(t); + } + } + + /** + * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input + * using only public methods available on the classpath. + * + * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in + * meaningful ways for a number of reasons. + * + * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}. + * @param func a method reference for the function to autofuzz. If there are multiple overloads, + * resolve ambiguities by explicitly casting to {@link Consumer4} with (partially) specified + * type variables. + * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link + * AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call. + * The {@link Throwable} is thrown unchecked. + */ + public static <T1, T2, T3, T4> void autofuzz( + FuzzedDataProvider data, Consumer4<T1, T2, T3, T4> func) { + try { + autofuzzConsumer4.invoke(data, func); + } catch (AutofuzzInvocationException e) { + rethrowUnchecked(e.getCause()); + } catch (Throwable t) { + rethrowUnchecked(t); + } + } + + /** + * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input + * using only public methods available on the classpath. + * + * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in + * meaningful ways for a number of reasons. + * + * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}. + * @param func a method reference for the function to autofuzz. If there are multiple overloads, + * resolve ambiguities by explicitly casting to {@link Consumer5} with (partially) specified + * type variables. + * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link + * AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call. + * The {@link Throwable} is thrown unchecked. + */ + public static <T1, T2, T3, T4, T5> void autofuzz( + FuzzedDataProvider data, Consumer5<T1, T2, T3, T4, T5> func) { + try { + autofuzzConsumer5.invoke(data, func); + } catch (AutofuzzInvocationException e) { + rethrowUnchecked(e.getCause()); + } catch (Throwable t) { + rethrowUnchecked(t); + } + } + + /** * Attempts to construct an instance of {@code type} from the fuzzer input using only public * methods available on the classpath. * diff --git a/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java b/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java index cd2ac875..66a85db6 100644 --- a/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java +++ b/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java @@ -37,6 +37,13 @@ public class AutofuzzTest { return impl != null; } + private static void checkAllTheArguments( + String arg1, int arg2, byte arg3, ImplementedInterface arg4) { + if (!arg1.equals("foobar") || arg2 != 42 || arg3 != 5 || arg4 == null) { + throw new IllegalArgumentException(); + } + } + @Test public void testConsume() { FuzzedDataProvider data = CannedFuzzedDataProvider.create( @@ -74,4 +81,27 @@ public class AutofuzzTest { } fail("should have thrown an AutofuzzConstructionException"); } + + @Test + public void testAutofuzzConsumer() { + FuzzedDataProvider data = CannedFuzzedDataProvider.create( + Arrays.asList((byte) 1 /* do not return null */, 6 /* string length */, "foobar", 42, + (byte) 5, (byte) 1 /* do not return null */, 0 /* first class on the classpath */, + (byte) 1 /* do not return null */, 0 /* first constructor */)); + Jazzer.autofuzz(data, AutofuzzTest::checkAllTheArguments); + } + + @Test + public void testAutofuzzConsumerThrowsException() { + FuzzedDataProvider data = + CannedFuzzedDataProvider.create(Arrays.asList((byte) 1 /* do not return null */, + 6 /* string length */, "foobar", 42, (byte) 5, (byte) 0 /* *do* return null */)); + try { + Jazzer.autofuzz(data, AutofuzzTest::checkAllTheArguments); + } catch (IllegalArgumentException e) { + // Pass. + return; + } + fail("should have thrown an IllegalArgumentException"); + } } |