aboutsummaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-10-21 11:22:26 +0200
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-10-21 15:49:56 +0200
commitafc33e3718f0f399c31dc47001ae90b7eee1a714 (patch)
tree1703bf7e0bd34f9f7a969c891b5031f2526502fb /agent
parent506d2115a10a0e292a11b36c7e99eda6cd21096f (diff)
downloadjazzer-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.java34
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java1
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java1
-rw-r--r--agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java32
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");
+ }
}