diff --git a/.github/workflows/fuzzing-featured.yaml b/.github/workflows/fuzzing-featured.yaml
index bdf608c2b..a5680d5b9 100644
--- a/.github/workflows/fuzzing-featured.yaml
+++ b/.github/workflows/fuzzing-featured.yaml
@@ -57,7 +57,7 @@ jobs:
shell: bash
- id: build-jazzer
name: Build Jazzer deps
- run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz
+ run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz //selffuzz:jazzer_api_selffuzz
- id: build-fuzzers
name: Build Fuzzers
diff --git a/.github/workflows/fuzzing.yaml b/.github/workflows/fuzzing.yaml
index 45d42dd69..13a8ef5c4 100644
--- a/.github/workflows/fuzzing.yaml
+++ b/.github/workflows/fuzzing.yaml
@@ -49,7 +49,7 @@ jobs:
shell: bash
- id: build-jazzer
name: Build Jazzer deps
- run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz
+ run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz //selffuzz:jazzer_api_selffuzz
- id: build-fuzzers
name: Build Fuzzers
diff --git a/selffuzz/BUILD.bazel b/selffuzz/BUILD.bazel
index c6298e6fe..44ea77ec8 100644
--- a/selffuzz/BUILD.bazel
+++ b/selffuzz/BUILD.bazel
@@ -6,3 +6,10 @@ jar_jar(
rules = "selffuzz_shade_rules.jarjar",
visibility = ["__subpackages__"],
)
+
+jar_jar(
+ name = "jazzer_api_selffuzz",
+ input_jar = "//src/main/java/com/code_intelligence/jazzer/api:api",
+ rules = "selffuzz_shade_rules.jarjar",
+ visibility = ["__subpackages__"],
+)
diff --git a/selffuzz/pom.xml b/selffuzz/pom.xml
index 82cc5511f..39026a16e 100644
--- a/selffuzz/pom.xml
+++ b/selffuzz/pom.xml
@@ -121,6 +121,13 @@
system
${project.basedir}/../bazel-bin/selffuzz/jazzer_selffuzz.jar
+
+ com.code-intelligence.selffuzz
+ jazzer-api
+ dev
+ system
+ ${project.basedir}/../bazel-bin/selffuzz/jazzer_api_selffuzz.jar
+
com.google.truth
truth
diff --git a/selffuzz/selffuzz_shade_rules.jarjar b/selffuzz/selffuzz_shade_rules.jarjar
index 8e508db58..61aab6968 100644
--- a/selffuzz/selffuzz_shade_rules.jarjar
+++ b/selffuzz/selffuzz_shade_rules.jarjar
@@ -1 +1,5 @@
+# this is loaded in a special way at runtime and so we can't shade it but it should be safe to share between selffuzz
+# and normal jazzer. In order to not shade it, we make a rule to transform it to itself and then have the
+# general rule because a file will be transformed by the first rule where it fits the filter
+rule com.code_intelligence.jazzer.utils.UnsafeProvider com.code_intelligence.jazzer.utils.UnsafeProvider
rule com.code_intelligence.jazzer.** com.code_intelligence.selffuzz.jazzer.@1
diff --git a/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/BUILD.bazel b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/BUILD.bazel
new file mode 100644
index 000000000..69908255f
--- /dev/null
+++ b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/BUILD.bazel
@@ -0,0 +1,27 @@
+load("//bazel:fuzz_target.bzl", "java_fuzz_target_test")
+
+# Mutator fuzz tests define a low `runs` to only start and iterate
+# a few times via Bazel. Long running fuzzing is executed in CI Sense through
+# the CI pipeline integration.
+
+java_fuzz_target_test(
+ name = "FuzzedDataProviderImplFuzzTest",
+ srcs = ["FuzzedDataProviderImplFuzzTest.java"],
+ fuzzer_args = [
+ "--experimental_mutator",
+ "-runs=1000",
+ ],
+ target_class = "com.code_intelligence.selffuzz.driver.FuzzedDataProviderImplFuzzTest",
+ verify_crash_reproducer = False,
+ deps = [
+ "//selffuzz:jazzer_api_selffuzz",
+ "//selffuzz:jazzer_selffuzz",
+ "//src/main/java/com/code_intelligence/jazzer/driver:fuzzed_data_provider_impl",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "//src/main/java/com/code_intelligence/jazzer/mutation/annotation",
+ "//src/main/native/com/code_intelligence/jazzer/driver:jazzer_fuzzed_data_provider",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ "@maven//:org_junit_jupiter_junit_jupiter_engine",
+ "@maven//:org_junit_platform_junit_platform_launcher",
+ ],
+)
diff --git a/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/FuzzedDataProviderImplFuzzTest.java b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/FuzzedDataProviderImplFuzzTest.java
new file mode 100644
index 000000000..a320bd0b1
--- /dev/null
+++ b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/FuzzedDataProviderImplFuzzTest.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright 2023 Code Intelligence GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.code_intelligence.selffuzz.driver;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import com.code_intelligence.jazzer.mutation.annotation.NotNull;
+import com.code_intelligence.selffuzz.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.selffuzz.jazzer.driver.FuzzedDataProviderImpl;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class FuzzedDataProviderImplFuzzTest {
+ @FuzzTest
+ void fuzzedDataProviderTest(byte @NotNull[] buf) {
+ try (FuzzedDataProviderImpl data = FuzzedDataProviderImpl.withJavaData(buf)) {
+ List> actionList = getActionList();
+
+ while (data.remainingBytes() > 0) {
+ Consumer action = data.pickValue(actionList);
+ action.accept(data);
+ }
+ }
+ }
+
+ List> getActionList() {
+ return Collections.unmodifiableList(Arrays.asList(
+ // clang-format off
+ // clang-format would compress this into multiple functions per line which I think looks worse
+ this::testBoolean,
+ this::testBooleans,
+ this::testByte,
+ this::testByteMinMax,
+ this::testBytes,
+ this::testRemainingAsBytes,
+ this::testShort,
+ this::testShortMinMax,
+ this::testShorts,
+ this::testInt,
+ this::testIntMinMax,
+ this::testInts,
+ this::testLong,
+ this::testLongMinMax,
+ this::testLongs,
+ this::testFloat,
+ this::testRegularFloat,
+ this::testRegularFloatMinMax,
+ this::testProbabilityFloat,
+ this::testDouble,
+ this::testRegularDouble,
+ this::testRegularDoubleMinMax,
+ this::testProbabilityDouble,
+ this::testChar,
+ this::testConsumeCharMinMax,
+ this::testCharNoSurrogates,
+ this::testString,
+ this::testRemainingAsString,
+ this::testAsciiString,
+ this::testRemainingAsAsciiString,
+ this::testPickValueCollection,
+ this::testPickValueArray,
+ this::testPickValueBoolean,
+ this::testPickValueByte,
+ this::testPickValueShort,
+ this::testPickValueInt,
+ this::testPickValueLong,
+ this::testPickValueDouble,
+ this::testPickValueFloat,
+ this::testPickValueChar,
+ this::testPickValuesCollection,
+ this::testPickValuesArray
+ // clang-format on
+ ));
+ }
+
+ void testBoolean(FuzzedDataProvider data) {
+ data.consumeBoolean();
+ }
+
+ void testBooleans(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ data.consumeBooleans(length);
+ }
+
+ void testByte(FuzzedDataProvider data) {
+ data.consumeByte();
+ }
+
+ void testByteMinMax(FuzzedDataProvider data) {
+ byte min = data.consumeByte();
+ byte max = data.consumeByte();
+ if (min > max) {
+ return;
+ }
+ data.consumeByte(min, max);
+ }
+
+ void testBytes(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ data.consumeBytes(length);
+ }
+
+ void testRemainingAsBytes(FuzzedDataProvider data) {
+ data.consumeRemainingAsBytes();
+ }
+
+ void testShort(FuzzedDataProvider data) {
+ data.consumeShort();
+ }
+
+ void testShortMinMax(FuzzedDataProvider data) {
+ short min = data.consumeShort();
+ short max = data.consumeShort();
+ if (min > max) {
+ return;
+ }
+ data.consumeShort(min, max);
+ }
+
+ void testShorts(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ data.consumeShorts(length);
+ }
+
+ void testInt(FuzzedDataProvider data) {
+ data.consumeInt();
+ }
+
+ void testIntMinMax(FuzzedDataProvider data) {
+ int min = data.consumeInt();
+ int max = data.consumeInt();
+ if (min > max) {
+ return;
+ }
+ data.consumeInt(min, max);
+ }
+
+ void testInts(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ data.consumeInts(length);
+ }
+
+ void testLong(FuzzedDataProvider data) {
+ data.consumeLong();
+ }
+
+ void testLongMinMax(FuzzedDataProvider data) {
+ long min = data.consumeLong();
+ long max = data.consumeLong();
+ if (min > max) {
+ return;
+ }
+ data.consumeLong(min, max);
+ }
+
+ void testLongs(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ data.consumeLongs(length);
+ }
+
+ void testFloat(FuzzedDataProvider data) {
+ data.consumeFloat();
+ }
+
+ void testRegularFloat(FuzzedDataProvider data) {
+ float f = data.consumeRegularFloat();
+ if (!Float.isFinite(f)) {
+ throw new RuntimeException("regular float has invalid value");
+ }
+ }
+
+ void testRegularFloatMinMax(FuzzedDataProvider data) {
+ float min = data.consumeFloat();
+ float max = data.consumeFloat();
+ if (!Float.isFinite(min) || !Float.isFinite(max)) {
+ return;
+ }
+ if (min > max) {
+ return;
+ }
+ float f = data.consumeRegularFloat(min, max);
+ if (!Float.isFinite(f)) {
+ throw new RuntimeException("regular float has invalid value");
+ }
+ if (f < min) {
+ throw new RuntimeException("output value is smaller than min");
+ }
+ if (f > max) {
+ throw new RuntimeException("output value is larger than max");
+ }
+ }
+
+ void testProbabilityFloat(FuzzedDataProvider data) {
+ float f = data.consumeProbabilityFloat();
+ if (f < 0.0 || f > 1.0) {
+ throw new RuntimeException("probability float has value outside [0.0, 1.0]");
+ }
+ }
+
+ void testDouble(FuzzedDataProvider data) {
+ data.consumeDouble();
+ }
+
+ void testRegularDouble(FuzzedDataProvider data) {
+ double d = data.consumeRegularDouble();
+ if (!Double.isFinite(d)) {
+ throw new RuntimeException("regular double has invalid value");
+ }
+ }
+
+ void testRegularDoubleMinMax(FuzzedDataProvider data) {
+ double min = data.consumeDouble();
+ double max = data.consumeDouble();
+ if (!Double.isFinite(min) || !Double.isFinite(max)) {
+ return;
+ }
+ if (min > max) {
+ return;
+ }
+ double d = data.consumeRegularDouble(min, max);
+ if (!Double.isFinite(d)) {
+ throw new RuntimeException("regular double has invalid value");
+ }
+ if (d < min) {
+ throw new RuntimeException("output value is smaller than min");
+ }
+ if (d > max) {
+ throw new RuntimeException("output value is larger than max");
+ }
+ }
+
+ void testProbabilityDouble(FuzzedDataProvider data) {
+ double d = data.consumeProbabilityDouble();
+ if (d < 0.0 || d > 1.0) {
+ throw new RuntimeException("probability double is outside [0.0, 1.0]");
+ }
+ }
+
+ void testChar(FuzzedDataProvider data) {
+ data.consumeChar();
+ }
+
+ void testConsumeCharMinMax(FuzzedDataProvider data) {
+ char min = data.consumeChar();
+ char max = data.consumeChar();
+ if (min > max) {
+ return;
+ }
+ data.consumeChar(min, max);
+ }
+
+ void testCharNoSurrogates(FuzzedDataProvider data) {
+ char c = data.consumeCharNoSurrogates();
+ if (Character.isSurrogate(c)) {
+ throw new RuntimeException("character was a surrogate");
+ }
+ }
+
+ void testString(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ data.consumeString(length);
+ }
+
+ void testRemainingAsString(FuzzedDataProvider data) {
+ data.consumeRemainingAsString();
+ }
+
+ void testAsciiString(FuzzedDataProvider data) {
+ int length = data.consumeInt();
+ if (length < 0) {
+ return;
+ }
+ String s = data.consumeAsciiString(length);
+ if (s.chars().anyMatch(c -> c >= 128)) {
+ throw new RuntimeException("ascii string contains character outside ascii range");
+ }
+ }
+
+ void testRemainingAsAsciiString(FuzzedDataProvider data) {
+ data.consumeRemainingAsAsciiString();
+ }
+
+ void testPickValueCollection(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ ArrayList collection = new ArrayList<>();
+ for (int i = 0; i < length; i++) {
+ collection.add(data.consumeInt());
+ }
+
+ data.pickValue(collection);
+ }
+
+ void testPickValueArray(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ Integer[] collection = new Integer[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeInt();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueBoolean(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ boolean[] collection = new boolean[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeBoolean();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueByte(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ byte[] collection = new byte[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeByte();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueShort(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ short[] collection = new short[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeShort();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueInt(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ int[] collection = new int[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeInt();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueLong(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ long[] collection = new long[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeLong();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueDouble(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ double[] collection = new double[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeDouble();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueFloat(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ float[] collection = new float[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeFloat();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValueChar(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ char[] collection = new char[length];
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeChar();
+ }
+ data.pickValue(collection);
+ }
+
+ void testPickValuesCollection(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ int numValues = data.consumeShort();
+ if (numValues > length) {
+ return;
+ }
+ ArrayList collection = new ArrayList<>();
+ for (int i = 0; i < length; i++) {
+ collection.add(data.consumeInt());
+ }
+
+ data.pickValues(collection, numValues);
+ }
+
+ void testPickValuesArray(FuzzedDataProvider data) {
+ int length = data.consumeShort();
+ if (length <= 0) {
+ return;
+ }
+ int numValues = data.consumeShort();
+ if (numValues > length) {
+ return;
+ }
+ Integer[] collection = new Integer[length];
+
+ for (int i = 0; i < length; i++) {
+ collection[i] = data.consumeInt();
+ }
+ data.pickValues(collection, numValues);
+ }
+}
diff --git a/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel b/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel
index 0d2efb002..6b5f3870a 100644
--- a/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel
+++ b/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel
@@ -125,8 +125,11 @@ java_jni_library(
java_jni_library(
name = "fuzzed_data_provider_impl",
srcs = ["FuzzedDataProviderImpl.java"],
- native_libs = ["//src/main/native/com/code_intelligence/jazzer/driver:jazzer_fuzzed_data_provider"],
+ native_libs = [
+ "//src/main/native/com/code_intelligence/jazzer/driver:jazzer_fuzzed_data_provider",
+ ],
visibility = [
+ "//selffuzz/src/test/java/com/code_intelligence/selffuzz/driver:__subpackages__",
"//src:__subpackages__",
],
deps = [
diff --git a/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel b/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel
index ea199635a..3e95ea114 100644
--- a/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel
+++ b/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel
@@ -71,7 +71,10 @@ cc_library(
cc_library(
name = "fuzzed_data_provider",
- srcs = ["fuzzed_data_provider.cpp"],
+ srcs = [
+ "com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h",
+ "fuzzed_data_provider.cpp",
+ ],
visibility = [
"//launcher:__pkg__",
],
@@ -85,8 +88,13 @@ cc_library(
cc_jni_library(
name = "jazzer_fuzzed_data_provider",
platforms = MULTI_PLATFORM,
- visibility = ["//src/main/java/com/code_intelligence/jazzer/driver:__pkg__"],
- deps = [":fuzzed_data_provider"],
+ visibility = [
+ "//selffuzz/src/test/java/com/code_intelligence/selffuzz/driver:__subpackages__",
+ "//src/main/java/com/code_intelligence/jazzer/driver:__pkg__",
+ ],
+ deps = [
+ ":fuzzed_data_provider",
+ ],
)
cc_library(
diff --git a/src/main/native/com/code_intelligence/jazzer/driver/com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h b/src/main/native/com/code_intelligence/jazzer/driver/com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h
new file mode 100644
index 000000000..0491f40ba
--- /dev/null
+++ b/src/main/native/com/code_intelligence/jazzer/driver/com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2023 Code Intelligence GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file was originally generated by cc_jni_library(name =
+ jazzer_fuzzed_data_provider_impl) and copied here and modified
+
+ Specifically it was taken from
+ `bazel-bin/src/main/java/com/code_intelligence/jazzer/driver/fuzzed_data_provider_impl.hdrs.h/com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl.h`
+ and modified such that all symbol names now include `selffuzz` in order to
+ be usable by our selffuzzing library. Due to the shading of our class files,
+ the selffuzz code will attempt to load symbols with the new classpath which
+ otherwise don't exist.
+
+ Normally the built jazzer jar will have a dylib (on Mac) in
+ `/com/code_intelligence/jazzer/driver/jazzer_fuzzed_data_provider_macos_aarch64/libjazzer_fuzzed_data_provider.dylib`
+
+ FuzzedDataProviderImpl will load that with a call to
+ ```
+ RulesJni.loadLibrary("jazzer_fuzzed_data_provider",
+ "/com/code_intelligence/jazzer/driver");
+ ```
+ which will look in a folder with that name plus architecture-specific bits
+ for a library to load.
+
+ Our shading utility properly changes that into
+ ```
+ RulesJni.loadLibrary("jazzer_fuzzed_data_provider",
+ "/com/code_intelligence/selffuzz/jazzer/driver");
+ ```
+ which is where that lib will be in the new jar and the shaded
+ FuzzedDataProviderImpl will load it but that library is not changed during
+ the shading so it will have the symbols defined at build time. When
+ FuzzedDataProviderImpl attempts to call
+ `Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_nativeInit`,
+ it will fail because the symbol does not exist.
+
+ Duplicating and renaming the symbols via this header file and copying and
+ renaming `nativeInit` in `fuzzed_data_provider.cpp` means that both the
+ normal and shaded FuzzedDataProviderImpls will be able to work. It would
+ probably be possible to remove this with some more selective build rules when
+ building a selffuzz jar.
+*/
+#include
+/* Header for class com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ */
+
+#ifndef _Included_com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl
+#define _Included_com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: nativeInit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_nativeInit(
+ JNIEnv *, jclass);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeBoolean
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeBoolean(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeBooleans
+ * Signature: (I)[Z
+ */
+JNIEXPORT jbooleanArray JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeBooleans(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeByte
+ * Signature: ()B
+ */
+JNIEXPORT jbyte JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeByte(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeShort
+ * Signature: ()S
+ */
+JNIEXPORT jshort JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeShort(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeShorts
+ * Signature: (I)[S
+ */
+JNIEXPORT jshortArray JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeShorts(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeInt
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeInt(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeInts
+ * Signature: (I)[I
+ */
+JNIEXPORT jintArray JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeInts(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeLong
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeLong(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeLongs
+ * Signature: (I)[J
+ */
+JNIEXPORT jlongArray JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeLongs(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeFloat
+ * Signature: ()F
+ */
+JNIEXPORT jfloat JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeFloat(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRegularFloat
+ * Signature: ()F
+ */
+JNIEXPORT jfloat JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularFloat(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeProbabilityFloat
+ * Signature: ()F
+ */
+JNIEXPORT jfloat JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeProbabilityFloat(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeDouble
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeDouble(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRegularDouble
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularDouble(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeProbabilityDouble
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeProbabilityDouble(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeChar
+ * Signature: ()C
+ */
+JNIEXPORT jchar JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeChar(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeCharNoSurrogates
+ * Signature: ()C
+ */
+JNIEXPORT jchar JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeCharNoSurrogates(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeAsciiString
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeAsciiString(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeString
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeString(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRemainingAsAsciiString
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRemainingAsAsciiString(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRemainingAsString
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRemainingAsString(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeBytes
+ * Signature: (I)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeBytes(
+ JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRemainingAsBytes
+ * Signature: ()[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRemainingAsBytes(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: remainingBytes
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_remainingBytes(
+ JNIEnv *, jobject);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeByteUnchecked
+ * Signature: (BB)B
+ */
+JNIEXPORT jbyte JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeByteUnchecked(
+ JNIEnv *, jobject, jbyte, jbyte);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeShortUnchecked
+ * Signature: (SS)S
+ */
+JNIEXPORT jshort JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeShortUnchecked(
+ JNIEnv *, jobject, jshort, jshort);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeCharUnchecked
+ * Signature: (CC)C
+ */
+JNIEXPORT jchar JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeCharUnchecked(
+ JNIEnv *, jobject, jchar, jchar);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeIntUnchecked
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeIntUnchecked(
+ JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeLongUnchecked
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeLongUnchecked(
+ JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRegularFloatUnchecked
+ * Signature: (FF)F
+ */
+JNIEXPORT jfloat JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularFloatUnchecked(
+ JNIEnv *, jobject, jfloat, jfloat);
+
+/*
+ * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl
+ * Method: consumeRegularDoubleUnchecked
+ * Signature: (DD)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularDoubleUnchecked(
+ JNIEnv *, jobject, jdouble, jdouble);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp b/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp
index 7ea9c3445..7a2c0158e 100644
--- a/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp
+++ b/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp
@@ -51,6 +51,8 @@
#include
#include "com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl.h"
+// see the header file for an explanation of why this is here
+#include "com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h"
namespace {
@@ -690,3 +692,12 @@ Java_com_code_1intelligence_jazzer_driver_FuzzedDataProviderImpl_nativeInit(
gDataPtrField = env->GetFieldID(clazz, "dataPtr", "J");
gRemainingBytesField = env->GetFieldID(clazz, "remainingBytes", "I");
}
+
+// duplicate nativeInit for selffuzz (see the selffuzz header file)
+[[maybe_unused]] void
+Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_nativeInit(
+ JNIEnv *env, jclass clazz) {
+ env->RegisterNatives(clazz, kFuzzedDataMethods, kNumFuzzedDataMethods);
+ gDataPtrField = env->GetFieldID(clazz, "dataPtr", "J");
+ gRemainingBytesField = env->GetFieldID(clazz, "remainingBytes", "I");
+}