diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2021-10-21 11:22:26 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-21 15:49:56 +0200 |
commit | afc33e3718f0f399c31dc47001ae90b7eee1a714 (patch) | |
tree | 1703bf7e0bd34f9f7a969c891b5031f2526502fb /agent | |
parent | 506d2115a10a0e292a11b36c7e99eda6cd21096f (diff) | |
download | jazzer-api-afc33e3718f0f399c31dc47001ae90b7eee1a714.tar.gz |
Add Jazzer.autofuzz(FuzzedDataProvider, Function1) to the Jazzer API
Also moves AutofuzzInvocationException to the api package.
Diffstat (limited to 'agent')
-rw-r--r-- | agent/src/main/java/com/code_intelligence/jazzer/api/AutofuzzInvocationException.java (renamed from agent/src/main/java/com/code_intelligence/jazzer/autofuzz/AutofuzzInvocationException.java) | 7 | ||||
-rw-r--r-- | agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java | 34 | ||||
-rw-r--r-- | agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java | 1 | ||||
-rw-r--r-- | agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java | 1 | ||||
-rw-r--r-- | agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java | 32 |
5 files changed, 72 insertions, 3 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/AutofuzzInvocationException.java b/agent/src/main/java/com/code_intelligence/jazzer/api/AutofuzzInvocationException.java index 8e586c4f..7e6203ce 100644 --- a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/AutofuzzInvocationException.java +++ b/agent/src/main/java/com/code_intelligence/jazzer/api/AutofuzzInvocationException.java @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.code_intelligence.jazzer.autofuzz; +package com.code_intelligence.jazzer.api; +// An exception wrapping a {@link Throwable} thrown during the actual invocation of, but not the +// construction of parameters for an autofuzzed method. /** - * An exception wrapping a {@link Throwable} thrown during the actual invocation of, but not the - * construction of parameters for an autofuzzed method. + * Only used internally. */ public class AutofuzzInvocationException extends RuntimeException { public AutofuzzInvocationException(Throwable cause) { 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 930d8f0f..d3826ee7 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 @@ -30,6 +30,7 @@ final public class Jazzer { private static MethodHandle traceMemcmp = null; private static MethodHandle consume = null; + private static MethodHandle autofuzzFunction1 = null; static { try { @@ -55,6 +56,9 @@ final public class Jazzer { MethodType consumeType = MethodType.methodType(Object.class, FuzzedDataProvider.class, Class.class); consume = MethodHandles.publicLookup().findStatic(metaClass, "consume", consumeType); + + autofuzzFunction1 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz", + MethodType.methodType(Object.class, FuzzedDataProvider.class, Function1.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. @@ -70,6 +74,36 @@ final public class Jazzer { private 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 Function1} with (partially) specified + * type variables, e.g. {@code (Function1<String, ?>) String::new}. + * @return the return value of {@code func}, or {@code null} if {@code autofuzz} failed to invoke + * the function. + * @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. + */ + @SuppressWarnings("unchecked") + public static <T1, R> R autofuzz(FuzzedDataProvider data, Function1<T1, R> func) { + try { + return (R) autofuzzFunction1.invoke(data, func); + } catch (AutofuzzInvocationException e) { + rethrowUnchecked(e.getCause()); + } catch (Throwable t) { + rethrowUnchecked(t); + } + // Not reached. + return null; + } + + /** * 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/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java index ce7df069..9c1c93ed 100644 --- a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java +++ b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java @@ -15,6 +15,7 @@ package com.code_intelligence.jazzer.autofuzz; import com.code_intelligence.jazzer.api.AutofuzzConstructionException; +import com.code_intelligence.jazzer.api.AutofuzzInvocationException; import com.code_intelligence.jazzer.api.FuzzedDataProvider; import com.code_intelligence.jazzer.utils.SimpleGlobMatcher; import com.code_intelligence.jazzer.utils.Utils; 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 4c4e1e32..be007984 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 @@ -15,6 +15,7 @@ package com.code_intelligence.jazzer.autofuzz; import com.code_intelligence.jazzer.api.AutofuzzConstructionException; +import com.code_intelligence.jazzer.api.AutofuzzInvocationException; import com.code_intelligence.jazzer.api.Consumer1; import com.code_intelligence.jazzer.api.Consumer2; import com.code_intelligence.jazzer.api.Consumer3; 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 b4696ce8..cd2ac875 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 @@ -14,8 +14,10 @@ package com.code_intelligence.jazzer.api; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import java.util.Arrays; import java.util.Collections; @@ -27,6 +29,14 @@ public class AutofuzzTest { public interface ImplementedInterface {} public static class ImplementingClass implements ImplementedInterface {} + private static boolean implIsNotNull(ImplementedInterface impl) { + return impl != null; + } + + private static boolean implIsNotNull(UnimplementedInterface impl) { + return impl != null; + } + @Test public void testConsume() { FuzzedDataProvider data = CannedFuzzedDataProvider.create( @@ -42,4 +52,26 @@ public class AutofuzzTest { (byte) 1 /* do not return null without searching for implementing classes */)); assertNull(Jazzer.consume(data, UnimplementedInterface.class)); } + + @Test + public void testAutofuzz() { + FuzzedDataProvider data = CannedFuzzedDataProvider.create( + Arrays.asList((byte) 1 /* do not return null */, 0 /* first class on the classpath */, + (byte) 1 /* do not return null */, 0 /* first constructor */)); + assertEquals(Boolean.TRUE, + Jazzer.autofuzz(data, (Function1<ImplementedInterface, ?>) AutofuzzTest::implIsNotNull)); + } + + @Test + public void testAutofuzzFailsWithException() { + FuzzedDataProvider data = CannedFuzzedDataProvider.create( + Collections.singletonList((byte) 1 /* do not return null */)); + try { + Jazzer.autofuzz(data, (Function1<UnimplementedInterface, ?>) AutofuzzTest::implIsNotNull); + } catch (AutofuzzConstructionException e) { + // Pass. + return; + } + fail("should have thrown an AutofuzzConstructionException"); + } } |