aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/BUILD.bazel187
-rw-r--r--examples/junit-spring-web/.gitignore33
-rw-r--r--examples/junit-spring-web/.mvn/wrapper/maven-wrapper.jarbin0 -> 58727 bytes
-rw-r--r--examples/junit-spring-web/.mvn/wrapper/maven-wrapper.properties2
-rwxr-xr-xexamples/junit-spring-web/build-and-run-tests.sh138
-rwxr-xr-xexamples/junit-spring-web/mvnw316
-rw-r--r--examples/junit-spring-web/mvnw.cmd188
-rw-r--r--examples/junit-spring-web/pom.xml73
-rw-r--r--examples/junit-spring-web/src/main/java/com/example/JunitSpringWebApplication.java87
-rw-r--r--examples/junit-spring-web/src/main/resources/application.properties0
-rw-r--r--examples/junit-spring-web/src/test/java/com/example/JunitSpringWebApplicationTests.java100
-rw-r--r--examples/junit-spring-web/src/test/resources/application.properties1
-rw-r--r--examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/Test-0011
-rw-r--r--examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-11f9578d05e6f7bb58a3cdd00107e9f4e38826711
-rw-r--r--examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730bin0 -> 15 bytes
-rw-r--r--examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/Test-0011
-rw-r--r--examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-11f9578d05e6f7bb58a3cdd00107e9f4e38826711
-rw-r--r--examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730bin0 -> 15 bytes
-rw-r--r--examples/junit-spring-web/src/test/resources/junit-platform.properties1
-rw-r--r--examples/junit/.gitignore2
-rw-r--r--examples/junit/pom.xml66
-rw-r--r--examples/junit/src/main/java/com/example/BUILD.bazel5
-rw-r--r--examples/junit/src/main/java/com/example/Parser.java25
-rw-r--r--examples/junit/src/test/java/com/example/AutofuzzFuzzTest.java41
-rw-r--r--examples/junit/src/test/java/com/example/AutofuzzLifecycleFuzzTest.java46
-rw-r--r--examples/junit/src/test/java/com/example/AutofuzzWithCorpusFuzzTest.java26
-rw-r--r--examples/junit/src/test/java/com/example/BUILD.bazel232
-rw-r--r--examples/junit/src/test/java/com/example/ByteFuzzTest.java33
-rw-r--r--examples/junit/src/test/java/com/example/CommandLineFuzzTest.java38
-rw-r--r--examples/junit/src/test/java/com/example/CorpusDirectoryFuzzTest.java45
-rw-r--r--examples/junit/src/test/java/com/example/DirectoryInputsFuzzTest.java39
-rw-r--r--examples/junit/src/test/java/com/example/HermeticInstrumentationFuzzTest.java63
-rw-r--r--examples/junit/src/test/java/com/example/InvalidFuzzTests.java23
-rw-r--r--examples/junit/src/test/java/com/example/JavaBinarySeedFuzzTest.java66
-rw-r--r--examples/junit/src/test/java/com/example/JavaSeedFuzzTest.java58
-rw-r--r--examples/junit/src/test/java/com/example/KeepGoingFuzzTest.java34
-rw-r--r--examples/junit/src/test/java/com/example/LifecycleFuzzTest.java94
-rw-r--r--examples/junit/src/test/java/com/example/MockitoFuzzTest.java36
-rw-r--r--examples/junit/src/test/java/com/example/MutatorFuzzTest.java46
-rw-r--r--examples/junit/src/test/java/com/example/ThrowingFuzzTest.java25
-rw-r--r--examples/junit/src/test/java/com/example/ValidFuzzTests.java76
-rw-r--r--examples/junit/src/test/java/com/example/ValueProfileFuzzTest.java39
-rw-r--r--examples/junit/src/test/resources/BUILD.bazel11
-rw-r--r--examples/junit/src/test/resources/com/example/AutofuzzWithCorpusFuzzTestInputs/autofuzzWithCorpus/crashing_inputbin0 -> 14 bytes
-rw-r--r--examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/fails1
-rw-r--r--examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/succeeds1
-rw-r--r--examples/junit/src/test/resources/com/example/MutatorFuzzTestInputs/mutatorFuzz/invalid1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/assert1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/honeypot1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_internal_class1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_user_class1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/assert1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/honeypot1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_internal_class1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_user_class1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/assert1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/honeypot1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_internal_class1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_user_class1
-rw-r--r--examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/no_crash1
-rw-r--r--examples/junit/src/test/resources/com/example/ValueProfileFuzzTestInputs/valueProfileFuzz/empty_seed0
-rw-r--r--examples/junit/src/test/resources/junit-platform.properties1
-rw-r--r--examples/src/main/java/com/example/BatikTranscoderFuzzer.java44
-rw-r--r--examples/src/main/java/com/example/CommonsTextFuzzer.java28
-rw-r--r--examples/src/main/java/com/example/ExampleFuzzerWithNative.java2
-rw-r--r--examples/src/main/java/com/example/ExampleKotlinFuzzer.kt38
-rw-r--r--examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt37
-rw-r--r--examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java12
-rw-r--r--examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java4
-rw-r--r--examples/src/main/java/com/example/MazeFuzzer.java15
-rw-r--r--examples/src/main/native/com/example/BUILD.bazel10
-rw-r--r--examples/src/main/native/com/example/com_example_ExampleFuzzerWithNative.cpp7
72 files changed, 2453 insertions, 60 deletions
diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel
index 599b8261..1a7da538 100644
--- a/examples/BUILD.bazel
+++ b/examples/BUILD.bazel
@@ -2,14 +2,13 @@ load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
load("@fmeum_rules_jni//jni:defs.bzl", "java_jni_library")
load("//bazel:compat.bzl", "SKIP_ON_MACOS", "SKIP_ON_WINDOWS")
load("//bazel:fuzz_target.bzl", "java_fuzz_target_test")
+load("//bazel:kotlin.bzl", "ktlint")
java_fuzz_target_test(
name = "Autofuzz",
- expected_findings = ["java.lang.ArrayIndexOutOfBoundsException"],
+ allowed_findings = ["java.lang.ArrayIndexOutOfBoundsException"],
fuzzer_args = [
"--autofuzz=com.google.json.JsonSanitizer::sanitize",
- # Exit after the first finding for testing purposes.
- "--keep_going=1",
],
runtime_deps = [
"@maven//:com_mikesamuel_json_sanitizer",
@@ -18,13 +17,22 @@ java_fuzz_target_test(
java_fuzz_target_test(
name = "ExampleFuzzer",
- srcs = [
- "src/main/java/com/example/ExampleFuzzer.java",
- "src/main/java/com/example/ExampleFuzzerHooks.java",
- ],
- # Comment out the next line to keep the fuzzer running indefinitely.
- hook_classes = ["com.example.ExampleFuzzerHooks"],
+ srcs = ["src/main/java/com/example/ExampleFuzzer.java"],
+ allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium"],
+ hook_jar = "ExampleFuzzerHooks_deploy.jar",
target_class = "com.example.ExampleFuzzer",
+ # Does not crash due to not using the hook.
+ verify_crash_reproducer = False,
+)
+
+java_binary(
+ name = "ExampleFuzzerHooks",
+ srcs = ["src/main/java/com/example/ExampleFuzzerHooks.java"],
+ create_executable = False,
+ # Comment out the next line to keep the ExampleFuzzer running indefinitely - without the hook, it will never be able
+ # to pass the comparison with the random number.
+ deploy_manifest_lines = ["Jazzer-Hook-Classes: com.example.ExampleFuzzerHooks"],
+ deps = ["//src/main/java/com/code_intelligence/jazzer/api:hooks"],
)
java_jni_library(
@@ -38,14 +46,21 @@ java_jni_library(
],
visibility = ["//examples/src/main/native/com/example:__pkg__"],
deps = [
- "//agent:jazzer_api_compile_only",
+ "//deploy:jazzer-api",
],
)
java_fuzz_target_test(
name = "ExampleFuzzerWithASan",
- fuzzer_args = ["--jvm_args=-Djazzer.native_lib=native_asan"],
- sanitizer = "address",
+ allowed_findings = ["native"],
+ env = {"EXAMPLE_NATIVE_LIB": "native_asan"},
+ env_inherit = ["CC"],
+ fuzzer_args = [
+ "--asan",
+ ],
+ # The shell launcher generated by Jazzer is killed in CI, even with codesigning disabled on the
+ # Java binary. This is not reproducible locally or with JDK 17.
+ tags = ["no-macos-x86_64-jdk8"],
target_class = "com.example.ExampleFuzzerWithNative",
target_compatible_with = SKIP_ON_WINDOWS,
verify_crash_reproducer = False,
@@ -56,8 +71,15 @@ java_fuzz_target_test(
java_fuzz_target_test(
name = "ExampleFuzzerWithUBSan",
- fuzzer_args = ["--jvm_args=-Djazzer.native_lib=native_ubsan"],
- sanitizer = "undefined",
+ allowed_findings = ["native"],
+ env = {"EXAMPLE_NATIVE_LIB": "native_ubsan"},
+ env_inherit = ["CC"],
+ fuzzer_args = [
+ "--ubsan",
+ ],
+ # The shell launcher generated by Jazzer is killed in CI, even with codesigning disabled on the
+ # Java binary. This is not reproducible locally or with JDK 17.
+ tags = ["no-macos-x86_64-jdk8"],
target_class = "com.example.ExampleFuzzerWithNative",
# Crashes at runtime without an error message.
target_compatible_with = SKIP_ON_WINDOWS,
@@ -67,14 +89,23 @@ java_fuzz_target_test(
],
)
+java_binary(
+ name = "ExamplePathTraversalFuzzerHooks",
+ srcs = ["src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java"],
+ create_executable = False,
+ deploy_manifest_lines = ["Jazzer-Hook-Classes: com.example.ExamplePathTraversalFuzzerHooks"],
+ deps = ["//src/main/java/com/code_intelligence/jazzer/api:hooks"],
+)
+
java_fuzz_target_test(
name = "ExamplePathTraversalFuzzer",
srcs = [
"src/main/java/com/example/ExamplePathTraversalFuzzer.java",
- "src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java",
],
- hook_classes = ["com.example.ExamplePathTraversalFuzzerHooks"],
+ allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh"],
+ hook_jar = "ExamplePathTraversalFuzzerHooks_deploy.jar",
target_class = "com.example.ExamplePathTraversalFuzzer",
+ verify_crash_reproducer = False,
)
java_fuzz_target_test(
@@ -82,7 +113,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/ExampleValueProfileFuzzer.java",
],
- expected_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow"],
+ allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow"],
# Comment out the next line to keep the fuzzer running indefinitely.
fuzzer_args = ["-use_value_profile=1"],
target_class = "com.example.ExampleValueProfileFuzzer",
@@ -93,17 +124,21 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/MazeFuzzer.java",
],
- expected_findings = ["com.example.MazeFuzzer$$TreasureFoundException"],
+ allowed_findings = ["com.example.MazeFuzzer$$TreasureFoundException"],
fuzzer_args = ["-use_value_profile=1"],
target_class = "com.example.MazeFuzzer",
)
java_fuzz_target_test(
name = "ExampleOutOfMemoryFuzzer",
+ timeout = "short",
srcs = [
"src/main/java/com/example/ExampleOutOfMemoryFuzzer.java",
],
- expected_findings = ["java.lang.OutOfMemoryError"],
+ allowed_findings = [
+ "com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow",
+ "java.lang.OutOfMemoryError",
+ ],
fuzzer_args = ["--jvm_args=-Xmx512m"],
target_class = "com.example.ExampleOutOfMemoryFuzzer",
)
@@ -113,7 +148,10 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/ExampleStackOverflowFuzzer.java",
],
- expected_findings = ["java.lang.StackOverflowError"],
+ allowed_findings = [
+ "com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow",
+ "java.lang.StackOverflowError",
+ ],
target_class = "com.example.ExampleStackOverflowFuzzer",
# Crashes with a segfault before any stack trace printing is reached.
target_compatible_with = SKIP_ON_MACOS,
@@ -141,16 +179,37 @@ java_fuzz_target_test(
],
)
+# WARNING: This fuzz target uses a vulnerable version of Apache Commons Text, which could result in the execution
+# of arbitrary code during fuzzing if executed with an older JDK. Use at your own risk.
+java_fuzz_target_test(
+ name = "CommonsTextFuzzer",
+ size = "enormous",
+ srcs = [
+ "src/main/java/com/example/CommonsTextFuzzer.java",
+ ],
+ fuzzer_args = [
+ "-fork=8",
+ "-use_value_profile=1",
+ ],
+ tags = ["manual"],
+ target_class = "com.example.CommonsTextFuzzer",
+ verify_crash_reproducer = False,
+ deps = [
+ "@maven//:org_apache_commons_commons_text",
+ ],
+)
+
java_fuzz_target_test(
name = "JpegImageParserFuzzer",
size = "enormous",
srcs = [
"src/main/java/com/example/JpegImageParserFuzzer.java",
],
- expected_findings = ["java.lang.NegativeArraySizeException"],
+ allowed_findings = ["java.lang.NegativeArraySizeException"],
fuzzer_args = [
"-fork=2",
],
+ tags = ["exclusive-if-local"],
target_class = "com.example.JpegImageParserFuzzer",
# The exit codes of the forked libFuzzer processes are not picked up correctly.
target_compatible_with = SKIP_ON_MACOS,
@@ -164,7 +223,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/GifImageParserFuzzer.java",
],
- expected_findings = [
+ allowed_findings = [
"java.lang.ArrayIndexOutOfBoundsException",
"java.lang.IllegalArgumentException",
"java.lang.OutOfMemoryError",
@@ -192,7 +251,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/JsonSanitizerCrashFuzzer.java",
],
- expected_findings = ["java.lang.IndexOutOfBoundsException"],
+ allowed_findings = ["java.lang.IndexOutOfBoundsException"],
target_class = "com.example.JsonSanitizerCrashFuzzer",
deps = [
"@maven//:com_mikesamuel_json_sanitizer",
@@ -204,7 +263,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/JsonSanitizerDenylistFuzzer.java",
],
- expected_findings = ["java.lang.AssertionError"],
+ allowed_findings = ["java.lang.AssertionError"],
target_class = "com.example.JsonSanitizerDenylistFuzzer",
deps = [
"@maven//:com_mikesamuel_json_sanitizer",
@@ -219,7 +278,7 @@ java_binary(
main_class = "com.code_intelligence.jazzer.replay.Replayer",
runtime_deps = [
":JsonSanitizerDenylistFuzzer_target_deploy.jar",
- "//agent/src/main/java/com/code_intelligence/jazzer/replay:Replayer_deploy.jar",
+ "//src/main/java/com/code_intelligence/jazzer/replay:Replayer_deploy.jar",
],
)
@@ -245,7 +304,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/JsonSanitizerIdempotenceFuzzer.java",
],
- expected_findings = ["java.lang.AssertionError"],
+ allowed_findings = ["java.lang.AssertionError"],
target_class = "com.example.JsonSanitizerIdempotenceFuzzer",
deps = [
"@maven//:com_mikesamuel_json_sanitizer",
@@ -257,7 +316,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/JsonSanitizerValidJsonFuzzer.java",
],
- expected_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow"],
+ allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow"],
target_class = "com.example.JsonSanitizerValidJsonFuzzer",
deps = [
"@maven//:com_google_code_gson_gson",
@@ -270,7 +329,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/JacksonCborFuzzer.java",
],
- expected_findings = ["java.lang.NullPointerException"],
+ allowed_findings = ["java.lang.NullPointerException"],
target_class = "com.example.JacksonCborFuzzer",
deps = [
"@maven//:com_fasterxml_jackson_core_jackson_core",
@@ -284,7 +343,7 @@ java_fuzz_target_test(
srcs = [
"src/main/java/com/example/FastJsonFuzzer.java",
],
- expected_findings = ["java.lang.NumberFormatException"],
+ allowed_findings = ["java.lang.NumberFormatException"],
target_class = "com.example.FastJsonFuzzer",
deps = [
"@maven//:com_alibaba_fastjson",
@@ -297,17 +356,18 @@ kt_jvm_library(
"src/main/java/com/example/KlaxonFuzzer.kt",
],
deps = [
- "//agent:jazzer_api_compile_only",
+ "//deploy:jazzer-api",
"@maven//:com_beust_klaxon",
],
)
java_fuzz_target_test(
name = "KlaxonFuzzer",
- expected_findings = [
+ allowed_findings = [
"java.lang.ClassCastException",
"java.lang.IllegalStateException",
"java.lang.NumberFormatException",
+ "java.lang.NullPointerException",
],
fuzzer_args = [
"--keep_going=7",
@@ -316,6 +376,47 @@ java_fuzz_target_test(
runtime_deps = [":KlaxonFuzzTarget"],
)
+kt_jvm_library(
+ name = "ExampleKotlinFuzzTarget",
+ srcs = [
+ "src/main/java/com/example/ExampleKotlinFuzzer.kt",
+ ],
+ deps = [
+ "//deploy:jazzer-api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "ExampleKotlinFuzzer",
+ allowed_findings = [
+ "com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium",
+ ],
+ target_class = "com.example.ExampleKotlinFuzzer",
+ runtime_deps = [":ExampleKotlinFuzzTarget"],
+)
+
+kt_jvm_library(
+ name = "ExampleKotlinValueProfileFuzzTarget",
+ srcs = [
+ "src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt",
+ ],
+ deps = [
+ "//deploy:jazzer-api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "ExampleKotlinValueProfileFuzzer",
+ allowed_findings = [
+ "com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium",
+ ],
+ fuzzer_args = [
+ "-use_value_profile=1",
+ ],
+ target_class = "com.example.ExampleKotlinValueProfileFuzzer",
+ runtime_deps = [":ExampleKotlinValueProfileFuzzTarget"],
+)
+
java_fuzz_target_test(
name = "TurboJpegFuzzer",
srcs = [
@@ -327,8 +428,8 @@ java_fuzz_target_test(
fuzzer_args = [
"-rss_limit_mb=8196",
"--jvm_args=-Djava.library.path=../libjpeg_turbo",
+ "--ubsan",
],
- sanitizer = "address",
tags = ["manual"],
target_class = "com.example.TurboJpegFuzzer",
deps = [
@@ -336,11 +437,31 @@ java_fuzz_target_test(
],
)
+java_fuzz_target_test(
+ name = "BatikTranscoderFuzzer",
+ srcs = [
+ "src/main/java/com/example/BatikTranscoderFuzzer.java",
+ ],
+ allowed_findings = [
+ "com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium",
+ ],
+ target_class = "com.example.BatikTranscoderFuzzer",
+ verify_crash_reproducer = False,
+ deps = [
+ "@maven//:org_apache_xmlgraphics_batik_anim",
+ "@maven//:org_apache_xmlgraphics_batik_bridge",
+ "@maven//:org_apache_xmlgraphics_batik_css",
+ "@maven//:org_apache_xmlgraphics_batik_transcoder",
+ "@maven//:org_apache_xmlgraphics_batik_util",
+ ],
+)
+
java_binary(
name = "examples",
create_executable = False,
visibility = ["//visibility:public"],
runtime_deps = [
+ ":BatikTranscoderFuzzer_target_deploy.jar",
":ExampleFuzzer_target_deploy.jar",
":ExampleValueProfileFuzzer_target_deploy.jar",
":FastJsonFuzzer_target_deploy.jar",
@@ -349,3 +470,5 @@ java_binary(
":JsonSanitizerDenylistFuzzer_target_deploy.jar",
],
)
+
+ktlint()
diff --git a/examples/junit-spring-web/.gitignore b/examples/junit-spring-web/.gitignore
new file mode 100644
index 00000000..549e00a2
--- /dev/null
+++ b/examples/junit-spring-web/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/examples/junit-spring-web/.mvn/wrapper/maven-wrapper.jar b/examples/junit-spring-web/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 00000000..c1dd12f1
--- /dev/null
+++ b/examples/junit-spring-web/.mvn/wrapper/maven-wrapper.jar
Binary files differ
diff --git a/examples/junit-spring-web/.mvn/wrapper/maven-wrapper.properties b/examples/junit-spring-web/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 00000000..b74bf7fc
--- /dev/null
+++ b/examples/junit-spring-web/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
diff --git a/examples/junit-spring-web/build-and-run-tests.sh b/examples/junit-spring-web/build-and-run-tests.sh
new file mode 100755
index 00000000..a2c819fa
--- /dev/null
+++ b/examples/junit-spring-web/build-and-run-tests.sh
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+# 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.
+
+# Development-only. This script builds the example project against the local version of Jazzer,
+# runs its unit and fuzz tests, and compares the results with expected results.
+
+set -e
+( cd ../../ &&
+ bazel build //...
+)
+
+# Update jazzer version used for building this project in the pom.xml
+JAZZER_VERSION=$(grep -oP '(?<=JAZZER_VERSION = ")[^"]*' ../../maven.bzl)
+# Find line with "<artifactId>jazzer-junit</artifactId>" and replace the version in the next line
+sed -i "/<artifactId>jazzer-junit<\/artifactId>/ {n;s/<version>.*<\/version>/<version>$JAZZER_VERSION<\/version>/}" pom.xml
+
+# Add locally-built Jazzer to the Maven repository
+./mvnw install:install-file -Dfile=../../bazel-bin/deploy/jazzer-junit-project.jar -DpomFile=../../bazel-bin/deploy/jazzer-junit-pom.xml
+./mvnw install:install-file -Dfile=../../bazel-bin/deploy/jazzer-project.jar -DpomFile=../../bazel-bin/deploy/jazzer-pom.xml
+./mvnw install:install-file -Dfile=../../bazel-bin/deploy/jazzer-api-project.jar -DpomFile=../../bazel-bin/deploy/jazzer-api-pom.xml
+
+## Regression and unit tests
+echo "[SPRINGBOOT-JUNIT]: These unit and regression fuzz tests should pass"
+./mvnw test -Dtest="JunitSpringWebApplicationTests#unitTestShouldPass+fuzzTestShouldPass"
+
+echo "[SPRINGBOOT-JUNIT]: This regression fuzz test should fail."
+# Temporarily disable exit on error.
+set +e
+./mvnw test -Dtest="JunitSpringWebApplicationTests#fuzzTestShouldFail"
+declare -i exit_code=$?
+set -e
+
+# Assert that the test failed with exit code 1.
+if [ $exit_code -eq 1 ]
+then
+ echo "[SPRINGBOOT-JUNIT]: Expected failing fuzz tests: continuing"
+else
+ echo "[SPRINGBOOT-JUNIT]: Expected exit code 1, but got $exit_code"
+ exit 1
+fi
+
+## Fuzz tests
+echo "[SPRINGBOOT-JUNIT]: This fuzz test should pass"
+JAZZER_FUZZ=1 ./mvnw test -Dtest="JunitSpringWebApplicationTests#fuzzTestShouldPass"
+
+echo "[SPRINGBOOT-JUNIT]: This fuzz test should fail"
+set +e
+JAZZER_FUZZ=1 ./mvnw test -Dtest="JunitSpringWebApplicationTests#fuzzTestShouldFail"
+declare -i exit_code=$?
+set -e
+
+if [ $exit_code -eq 1 ]
+then
+ echo "[SPRINGBOOT-JUNIT]: Expected failing fuzz tests: continuing"
+else
+ echo "[SPRINGBOOT-JUNIT]: Expected exit code 1, but got $exit_code"
+ exit 1
+fi
+
+echo "[SPRINGBOOT-JUNIT]: This fuzz test using autofuzz should fail"
+set +e
+JAZZER_FUZZ=1 ./mvnw test -Dtest="JunitSpringWebApplicationTests#fuzzTestWithDtoShouldFail"
+declare -i exit_code=$?
+set -e
+
+if [ $exit_code -eq 1 ]
+then
+ echo "[SPRINGBOOT-JUNIT]: Expected failing fuzz tests: continuing"
+else
+ echo "[SPRINGBOOT-JUNIT]: Expected exit code 1, but got $exit_code"
+ exit 1
+fi
+
+## CLI tests
+## Assert transitive JUnit dependencies are specified
+assertDependency() {
+ if ./mvnw dependency:tree | grep -q "$1"
+ then
+ echo "[SPRINGBOOT-JUNIT]: Found $1 dependency in project"
+ else
+ echo "[SPRINGBOOT-JUNIT]: Did not find $1 dependency in project"
+ exit 1
+ fi
+}
+assertDependency "org.junit.jupiter:junit-jupiter-api"
+assertDependency "org.junit.jupiter:junit-jupiter-params"
+assertDependency "org.junit.platform:junit-platform-launcher"
+
+# Only build project and test jars, no need for a fat-jar or test execution
+./mvnw jar:jar
+./mvnw jar:test-jar
+
+# Extract dependency locations
+out=$(./mvnw dependency:build-classpath -DforceStdout)
+deps=$(echo "$out" | sed '/^\[/d')
+
+# Directly execute Jazzer without Maven
+echo "[SPRINGBOOT-JUNIT]: Direct Jazzer execution of fuzz test should pass"
+java -cp "target/*:${deps}" \
+ com.code_intelligence.jazzer.Jazzer \
+ --target_class=com.example.JunitSpringWebApplicationTests \
+ --target_method=fuzzTestShouldPass \
+ --instrumentation_includes=com.example.* \
+ --custom_hook_includes=com.example.*
+
+
+echo "[SPRINGBOOT-JUNIT]: Direct Jazzer execution of fuzz test using autofuzz should fail"
+set +e
+JAZZER_FUZZ=1 java -cp "target/*:${deps}" \
+ com.code_intelligence.jazzer.Jazzer \
+ --target_class=com.example.JunitSpringWebApplicationTests \
+ --target_method=fuzzTestWithDtoShouldFail \
+ --instrumentation_includes=com.example.* \
+ --custom_hook_includes=com.example.*
+declare -i exit_code=$?
+set -e
+
+if [ $exit_code -eq 77 ]
+then
+ echo "[SPRINGBOOT-JUNIT]: Expected failing fuzz tests: continuing"
+else
+ echo "[SPRINGBOOT-JUNIT]: Expected exit code 77, but got $exit_code"
+ exit 1
+fi
+
+echo "[SPRINGBOOT-JUNIT]: All tests passed"
diff --git a/examples/junit-spring-web/mvnw b/examples/junit-spring-web/mvnw
new file mode 100755
index 00000000..8a8fb228
--- /dev/null
+++ b/examples/junit-spring-web/mvnw
@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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
+#
+# https://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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/examples/junit-spring-web/mvnw.cmd b/examples/junit-spring-web/mvnw.cmd
new file mode 100644
index 00000000..1d8ab018
--- /dev/null
+++ b/examples/junit-spring-web/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/examples/junit-spring-web/pom.xml b/examples/junit-spring-web/pom.xml
new file mode 100644
index 00000000..b8714525
--- /dev/null
+++ b/examples/junit-spring-web/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-parent</artifactId>
+ <version>3.0.5</version>
+ <relativePath/> <!-- lookup parent from repository -->
+ </parent>
+
+ <groupId>com.example</groupId>
+ <artifactId>junit-spring-web</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>junit-spring-web</name>
+ <description>Demo project for Spring Boot</description>
+ <properties>
+ <java.version>11</java.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.code-intelligence</groupId>
+ <artifactId>jazzer-junit</artifactId>
+ <version>0.16.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <version>5.9.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/examples/junit-spring-web/src/main/java/com/example/JunitSpringWebApplication.java b/examples/junit-spring-web/src/main/java/com/example/JunitSpringWebApplication.java
new file mode 100644
index 00000000..148c4d44
--- /dev/null
+++ b/examples/junit-spring-web/src/main/java/com/example/JunitSpringWebApplication.java
@@ -0,0 +1,87 @@
+/*
+ * 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.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@SpringBootApplication
+@RestController
+public class JunitSpringWebApplication {
+ public static final class HelloRequest {
+ public static final HelloRequest DEFAULT = new HelloRequest();
+
+ String prefix = "Hello ";
+ String name = "World";
+ String suffix = "!";
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSuffix() {
+ return suffix;
+ }
+
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+ }
+
+ @GetMapping("/hello")
+ public String sayHello(@RequestParam(required = false, defaultValue = "World") String name) {
+ return "Hello " + name;
+ }
+
+ @GetMapping("/buggy-hello")
+ public String buggyHello(@RequestParam(required = false, defaultValue = "World") String name)
+ throws Error {
+ if (name.equals("error")) {
+ throw new Error("Error found!");
+ }
+ return "Hello " + name;
+ }
+
+ @PostMapping("/hello")
+ public String postHello(@RequestBody HelloRequest request) {
+ if ("error".equals(request.name)) {
+ throw new Error("Error found!");
+ }
+ return request.prefix + request.name + request.suffix;
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(JunitSpringWebApplication.class, args);
+ }
+}
diff --git a/examples/junit-spring-web/src/main/resources/application.properties b/examples/junit-spring-web/src/main/resources/application.properties
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/examples/junit-spring-web/src/main/resources/application.properties
diff --git a/examples/junit-spring-web/src/test/java/com/example/JunitSpringWebApplicationTests.java b/examples/junit-spring-web/src/test/java/com/example/JunitSpringWebApplicationTests.java
new file mode 100644
index 00000000..2cf356f2
--- /dev/null
+++ b/examples/junit-spring-web/src/test/java/com/example/JunitSpringWebApplicationTests.java
@@ -0,0 +1,100 @@
+/*
+ * 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.example;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import com.example.JunitSpringWebApplication.HelloRequest;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+@WebMvcTest
+public class JunitSpringWebApplicationTests {
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ @Autowired private MockMvc mockMvc;
+ private boolean beforeCalled = false;
+
+ @BeforeEach
+ public void beforeEach() {
+ beforeCalled = true;
+ }
+
+ @AfterEach
+ public void afterEach() {
+ beforeCalled = false;
+ }
+
+ @Test
+ public void unitTestShouldPass() throws Exception {
+ mockMvc.perform(get("/hello").param("name", "Maven"));
+ }
+
+ @Test
+ public void unitTestShouldFail() throws Exception {
+ mockMvc.perform(get("/buggy-hello").param("name", "error"));
+ }
+
+ @FuzzTest(maxDuration = "10s")
+ public void fuzzTestShouldPass(FuzzedDataProvider data) throws Exception {
+ if (!beforeCalled) {
+ throw new RuntimeException("BeforeEach was not called");
+ }
+
+ String name = data.consumeRemainingAsString();
+ mockMvc.perform(get("/hello").param("name", name));
+ }
+
+ @FuzzTest(maxDuration = "10s")
+ public void fuzzTestShouldFail(FuzzedDataProvider data) throws Exception {
+ if (!beforeCalled) {
+ throw new RuntimeException("BeforeEach was not called");
+ }
+
+ String name = data.consumeRemainingAsString();
+ mockMvc.perform(get("/buggy-hello").param("name", name))
+ .andExpect(content().string(containsString(name)));
+ }
+
+ @FuzzTest(maxDuration = "10s")
+ public void fuzzTestWithDtoShouldFail(HelloRequest helloRequest) throws Exception {
+ if (!beforeCalled) {
+ throw new RuntimeException("BeforeEach was not called");
+ }
+ Assumptions.assumeTrue(
+ helloRequest != null && helloRequest.name != null && !helloRequest.name.isBlank());
+
+ mockMvc
+ .perform(post("/hello")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(mapper.writeValueAsString(helloRequest)))
+ .andExpect(content().string(containsString(helloRequest.name)));
+ }
+}
diff --git a/examples/junit-spring-web/src/test/resources/application.properties b/examples/junit-spring-web/src/test/resources/application.properties
new file mode 100644
index 00000000..64c19670
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/application.properties
@@ -0,0 +1 @@
+logging.level.org.springframework.web=INFO
diff --git a/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/Test-001 b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/Test-001
new file mode 100644
index 00000000..760589cb
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/Test-001
@@ -0,0 +1 @@
+error \ No newline at end of file
diff --git a/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-11f9578d05e6f7bb58a3cdd00107e9f4e3882671 b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-11f9578d05e6f7bb58a3cdd00107e9f4e3882671
new file mode 100644
index 00000000..760589cb
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-11f9578d05e6f7bb58a3cdd00107e9f4e3882671
@@ -0,0 +1 @@
+error \ No newline at end of file
diff --git a/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730 b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730
new file mode 100644
index 00000000..58002425
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730
Binary files differ
diff --git a/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/Test-001 b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/Test-001
new file mode 100644
index 00000000..760589cb
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/Test-001
@@ -0,0 +1 @@
+error \ No newline at end of file
diff --git a/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-11f9578d05e6f7bb58a3cdd00107e9f4e3882671 b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-11f9578d05e6f7bb58a3cdd00107e9f4e3882671
new file mode 100644
index 00000000..760589cb
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-11f9578d05e6f7bb58a3cdd00107e9f4e3882671
@@ -0,0 +1 @@
+error \ No newline at end of file
diff --git a/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730 b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730
new file mode 100644
index 00000000..58002425
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/com/example/JunitSpringWebApplicationTestsInputs/fuzzTestWithDtoShouldFail/crash-4acd17b34d3dafa673ab1f7ade3a8a29582a5730
Binary files differ
diff --git a/examples/junit-spring-web/src/test/resources/junit-platform.properties b/examples/junit-spring-web/src/test/resources/junit-platform.properties
new file mode 100644
index 00000000..02290619
--- /dev/null
+++ b/examples/junit-spring-web/src/test/resources/junit-platform.properties
@@ -0,0 +1 @@
+jazzer.instrument=com.example.**,com.other.package.**
diff --git a/examples/junit/.gitignore b/examples/junit/.gitignore
new file mode 100644
index 00000000..f419dc7b
--- /dev/null
+++ b/examples/junit/.gitignore
@@ -0,0 +1,2 @@
+/.idea
+/target
diff --git a/examples/junit/pom.xml b/examples/junit/pom.xml
new file mode 100644
index 00000000..cd3bae94
--- /dev/null
+++ b/examples/junit/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2022 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.example</groupId>
+ <artifactId>jazzer-junit-example</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <version>5.9.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.code-intelligence</groupId>
+ <artifactId>jazzer-junit</artifactId>
+ <version>0.16.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>5.2.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.22.2</version>
+ </plugin>
+ </plugins>
+ <testResources>
+ <testResource>
+ <directory>${project.basedir}/src/test/resources</directory>
+ </testResource>
+ </testResources>
+ </build>
+
+</project>
diff --git a/examples/junit/src/main/java/com/example/BUILD.bazel b/examples/junit/src/main/java/com/example/BUILD.bazel
new file mode 100644
index 00000000..69654593
--- /dev/null
+++ b/examples/junit/src/main/java/com/example/BUILD.bazel
@@ -0,0 +1,5 @@
+java_library(
+ name = "parser",
+ srcs = ["Parser.java"],
+ visibility = ["//examples/junit/src/test/java/com/example:__pkg__"],
+)
diff --git a/examples/junit/src/main/java/com/example/Parser.java b/examples/junit/src/main/java/com/example/Parser.java
new file mode 100644
index 00000000..966a0d3e
--- /dev/null
+++ b/examples/junit/src/main/java/com/example/Parser.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 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.example;
+
+public class Parser {
+ public static void parse(byte[] data) {
+ if (data[4] == 'c' && new String(data).startsWith("aaaaaa")) {
+ throw new IllegalStateException("Not reached");
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/AutofuzzFuzzTest.java b/examples/junit/src/test/java/com/example/AutofuzzFuzzTest.java
new file mode 100644
index 00000000..4f316c34
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/AutofuzzFuzzTest.java
@@ -0,0 +1,41 @@
+// Copyright 2022 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.example;
+
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+class AutofuzzFuzzTest {
+ private static class IntHolder {
+ private final int i;
+
+ IntHolder(int i) {
+ this.i = i;
+ }
+
+ public int getI() {
+ return i;
+ }
+ }
+
+ @FuzzTest(maxDuration = "5m")
+ void autofuzz(String str, IntHolder holder) {
+ assumeTrue(holder != null);
+ if (holder.getI() == 1234 && str != null && str.contains("jazzer")) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/AutofuzzLifecycleFuzzTest.java b/examples/junit/src/test/java/com/example/AutofuzzLifecycleFuzzTest.java
new file mode 100644
index 00000000..b82f1aba
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/AutofuzzLifecycleFuzzTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.example;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.TestInstancePostProcessor;
+
+@TestMethodOrder(MethodOrderer.MethodName.class)
+@ExtendWith(AutofuzzLifecycleFuzzTest.AutofuzzLifecycleInstancePostProcessor.class)
+class AutofuzzLifecycleFuzzTest {
+ // Use a TestInstancePostProcessor to inject an object into the JUnit test instance,
+ // simulating other JUnit extensions like the Spring Boot Test, to check that autofuzz
+ // invokes the test function on the correct instance.
+ private Object injectedObject;
+
+ @FuzzTest(maxDuration = "1s")
+ void autofuzzLifecycleFuzz(String ignored, String ignoredAsWell) {
+ Assertions.assertNotNull(injectedObject);
+ }
+
+ static class AutofuzzLifecycleInstancePostProcessor implements TestInstancePostProcessor {
+ @Override
+ public void postProcessTestInstance(Object o, ExtensionContext extensionContext) {
+ ((AutofuzzLifecycleFuzzTest) o).injectedObject = new Object();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/AutofuzzWithCorpusFuzzTest.java b/examples/junit/src/test/java/com/example/AutofuzzWithCorpusFuzzTest.java
new file mode 100644
index 00000000..a5337035
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/AutofuzzWithCorpusFuzzTest.java
@@ -0,0 +1,26 @@
+// Copyright 2022 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.example;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+class AutofuzzWithCorpusFuzzTest {
+ @FuzzTest
+ void autofuzzWithCorpus(String str, int i) {
+ if ("jazzer".equals(str) && i == 1234) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/BUILD.bazel b/examples/junit/src/test/java/com/example/BUILD.bazel
new file mode 100644
index 00000000..8bbdcecd
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/BUILD.bazel
@@ -0,0 +1,232 @@
+load("//bazel:fuzz_target.bzl", "java_fuzz_target_test")
+
+java_binary(
+ name = "ExampleFuzzTests",
+ testonly = True,
+ srcs = glob(["*.java"]),
+ create_executable = False,
+ visibility = [
+ "//src/test/java/com/code_intelligence/jazzer/junit:__pkg__",
+ ],
+ deps = [
+ "//deploy:jazzer",
+ "//deploy:jazzer-api",
+ "//deploy:jazzer-junit",
+ "//examples/junit/src/main/java/com/example:parser",
+ "//examples/junit/src/test/resources:example_seed_corpora",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ "@maven//:org_junit_jupiter_junit_jupiter_params",
+ "@maven//:org_mockito_mockito_core",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "DataFuzzTest",
+ srcs = ["ValidFuzzTests.java"],
+ allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium"],
+ fuzzer_args = [
+ "-runs=0",
+ ],
+ target_class = "com.example.ValidFuzzTests",
+ target_method = "dataFuzz",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//examples/junit/src/main/java/com/example:parser",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "ByteFuzzTest",
+ srcs = ["ByteFuzzTest.java"],
+ allowed_findings = ["org.opentest4j.AssertionFailedError"],
+ fuzzer_args = [
+ "-runs=0",
+ ],
+ target_class = "com.example.ByteFuzzTest",
+ target_method = "byteFuzz",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//examples/junit/src/main/java/com/example:parser",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "LifecycleFuzzTest",
+ srcs = ["LifecycleFuzzTest.java"],
+ allowed_findings = ["java.io.IOException"],
+ fuzzer_args = [
+ "-runs=0",
+ ],
+ target_class = "com.example.LifecycleFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//examples/junit/src/main/java/com/example:parser",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "KeepGoingFuzzTest",
+ srcs = ["KeepGoingFuzzTest.java"],
+ allowed_findings = ["java.lang.IllegalArgumentException"],
+ expect_crash = False,
+ fuzzer_args = [
+ "--keep_going=3",
+ "-runs=10",
+ ],
+ target_class = "com.example.KeepGoingFuzzTest",
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+# Verifies that fuzzer command-line arguments are honored for @FuzzTests.
+java_fuzz_target_test(
+ name = "CommandLineFuzzTest",
+ srcs = ["CommandLineFuzzTest.java"],
+ allowed_findings = ["java.lang.Error"],
+ fuzzer_args = [
+ # Ignore the first two findings.
+ "--ignore=d5e250a5298b81e6,d86371e6d41739ec",
+ ],
+ target_class = "com.example.CommandLineFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//examples/junit/src/main/java/com/example:parser",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+# Verify that Mockito is properly ignored.
+# Using version 5+ could otherwise introduce cyclic instrumentation.
+java_fuzz_target_test(
+ name = "MockitoFuzzTest",
+ srcs = ["MockitoFuzzTest.java"],
+ fuzzer_args = [
+ "-runs=1",
+ ],
+ tags = ["no-jdk8"],
+ target_class = "com.example.MockitoFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//examples/junit/src/main/java/com/example:parser",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ "@maven//:org_mockito_mockito_core",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "AutofuzzLifecycleFuzzTest",
+ srcs = ["AutofuzzLifecycleFuzzTest.java"],
+ fuzzer_args = [
+ "-runs=0",
+ ],
+ target_class = "com.example.AutofuzzLifecycleFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "MutatorFuzzTest",
+ srcs = ["MutatorFuzzTest.java"],
+ allowed_findings = ["java.lang.AssertionError"],
+ data = [
+ "//examples/junit/src/test/resources:MutatorFuzzTestInputs",
+ ],
+ env = {
+ "JAZZER_FUZZ": "1",
+ },
+ fuzzer_args = [
+ "--experimental_mutator",
+ "$(rlocationpaths //examples/junit/src/test/resources:MutatorFuzzTestInputs)",
+ ],
+ target_class = "com.example.MutatorFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//src/main/java/com/code_intelligence/jazzer/driver:fuzz_target_runner",
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "//src/main/java/com/code_intelligence/jazzer/mutation/annotation",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "JavaSeedFuzzTest",
+ srcs = ["JavaSeedFuzzTest.java"],
+ allowed_findings = ["java.lang.Error"],
+ env = {"JAZZER_FUZZ": "1"},
+ fuzzer_args = [
+ "--experimental_mutator",
+ ],
+ target_class = "com.example.JavaSeedFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "//src/main/java/com/code_intelligence/jazzer/mutation/annotation",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ "@maven//:org_junit_jupiter_junit_jupiter_params",
+ ],
+)
+
+java_fuzz_target_test(
+ name = "JavaBinarySeedFuzzTest",
+ srcs = ["JavaBinarySeedFuzzTest.java"],
+ allowed_findings = ["java.lang.Error"],
+ env = {"JAZZER_FUZZ": "1"},
+ target_class = "com.example.JavaBinarySeedFuzzTest",
+ verify_crash_reproducer = False,
+ runtime_deps = [
+ ":junit_runtime",
+ ],
+ deps = [
+ "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test",
+ "@maven//:org_junit_jupiter_junit_jupiter_api",
+ "@maven//:org_junit_jupiter_junit_jupiter_params",
+ ],
+)
+
+java_library(
+ name = "junit_runtime",
+ runtime_deps = [
+ "@maven//:org_junit_jupiter_junit_jupiter_engine",
+ "@maven//:org_junit_platform_junit_platform_launcher",
+ ],
+)
diff --git a/examples/junit/src/test/java/com/example/ByteFuzzTest.java b/examples/junit/src/test/java/com/example/ByteFuzzTest.java
new file mode 100644
index 00000000..506ef892
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/ByteFuzzTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 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.example;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+class ByteFuzzTest {
+ @FuzzTest
+ void byteFuzz(byte[] data) {
+ if (data.length < 1) {
+ return;
+ }
+ if (data[0] % 2 == 0) {
+ fail();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/CommandLineFuzzTest.java b/examples/junit/src/test/java/com/example/CommandLineFuzzTest.java
new file mode 100644
index 00000000..e79d4638
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/CommandLineFuzzTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.example;
+
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+class CommandLineFuzzTest {
+ int run = 0;
+
+ @FuzzTest
+ void commandLineFuzz(byte[] bytes) {
+ assumeTrue(bytes.length > 0);
+ switch (run++) {
+ case 0:
+ throw new RuntimeException();
+ case 1:
+ throw new IllegalStateException();
+ case 2:
+ throw new Error();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/CorpusDirectoryFuzzTest.java b/examples/junit/src/test/java/com/example/CorpusDirectoryFuzzTest.java
new file mode 100644
index 00000000..465c94cf
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/CorpusDirectoryFuzzTest.java
@@ -0,0 +1,45 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+public class CorpusDirectoryFuzzTest {
+ private static int invocations = 0;
+
+ @FuzzTest(maxDuration = "5s")
+ public void corpusDirectoryFuzz(FuzzedDataProvider data) {
+ // Throw on the third invocation to generate corpus entries.
+ if (data.remainingBytes() == 0) {
+ return;
+ }
+ // Add a few branch statements to generate different coverage.
+ switch (invocations) {
+ case 0:
+ invocations++;
+ break;
+ case 1:
+ invocations++;
+ break;
+ case 2:
+ invocations++;
+ break;
+ case 3:
+ throw new FuzzerSecurityIssueMedium();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/DirectoryInputsFuzzTest.java b/examples/junit/src/test/java/com/example/DirectoryInputsFuzzTest.java
new file mode 100644
index 00000000..1d1ce2c4
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/DirectoryInputsFuzzTest.java
@@ -0,0 +1,39 @@
+// Copyright 2022 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+public class DirectoryInputsFuzzTest {
+ private static boolean firstSeed = true;
+
+ @FuzzTest(maxDuration = "0s")
+ public void inputsFuzz(FuzzedDataProvider data) {
+ // Only execute the fuzz test logic on the empty input and the only seed.
+ if (data.remainingBytes() == 0) {
+ return;
+ }
+ String input = data.consumeRemainingAsString();
+ if (!firstSeed && !input.equals("directory")) {
+ throw new IllegalStateException("Should have crashed on the first non-empty input");
+ }
+ firstSeed = false;
+ if (input.equals("directory")) {
+ throw new FuzzerSecurityIssueMedium();
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/HermeticInstrumentationFuzzTest.java b/examples/junit/src/test/java/com/example/HermeticInstrumentationFuzzTest.java
new file mode 100644
index 00000000..97e03811
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/HermeticInstrumentationFuzzTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 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.example;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import java.util.regex.Pattern;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Execution;
+import org.junit.jupiter.api.parallel.ExecutionMode;
+
+@SuppressWarnings("InvalidPatternSyntax")
+@Execution(ExecutionMode.CONCURRENT)
+class HermeticInstrumentationFuzzTest {
+ class VulnerableFuzzClass {
+ public void vulnerableMethod(String input) {
+ Pattern.compile(input);
+ }
+ }
+
+ class VulnerableUnitClass {
+ public void vulnerableMethod(String input) {
+ Pattern.compile(input);
+ }
+ }
+
+ @FuzzTest
+ @Execution(ExecutionMode.CONCURRENT)
+ void fuzzTest1(byte[] data) {
+ new VulnerableFuzzClass().vulnerableMethod("[");
+ }
+
+ @Test
+ @Execution(ExecutionMode.CONCURRENT)
+ void unitTest1() {
+ new VulnerableUnitClass().vulnerableMethod("[");
+ }
+
+ @FuzzTest
+ @Execution(ExecutionMode.CONCURRENT)
+ void fuzzTest2(byte[] data) {
+ Pattern.compile("[");
+ }
+
+ @Test
+ @Execution(ExecutionMode.CONCURRENT)
+ void unitTest2() {
+ Pattern.compile("[");
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/InvalidFuzzTests.java b/examples/junit/src/test/java/com/example/InvalidFuzzTests.java
new file mode 100644
index 00000000..acaecb8c
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/InvalidFuzzTests.java
@@ -0,0 +1,23 @@
+// Copyright 2022 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+class InvalidFuzzTests {
+ @FuzzTest
+ void invalidParameterCountFuzz() {}
+}
diff --git a/examples/junit/src/test/java/com/example/JavaBinarySeedFuzzTest.java b/examples/junit/src/test/java/com/example/JavaBinarySeedFuzzTest.java
new file mode 100644
index 00000000..70b35352
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/JavaBinarySeedFuzzTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.example;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import org.junit.jupiter.params.converter.ArgumentConversionException;
+import org.junit.jupiter.params.converter.ConvertWith;
+import org.junit.jupiter.params.converter.SimpleArgumentConverter;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class JavaBinarySeedFuzzTest {
+ // Generated via:
+ // printf 'tH15_1S-4_53Cr3T.fl4G' | openssl dgst -binary -sha256 | openssl base64 -A
+ // Luckily the fuzzer can't read comments ;-)
+ private static final byte[] FLAG_SHA256 =
+ Base64.getDecoder().decode("q0vPdz5oeJIW3k2U4VJ+aWDufzzZbKAcevc9cNoUTSM=");
+
+ static class Utf8BytesConverter extends SimpleArgumentConverter {
+ @Override
+ protected Object convert(Object source, Class<?> targetType)
+ throws ArgumentConversionException {
+ assertEquals(byte[].class, targetType);
+ assertTrue(source instanceof byte[] || source instanceof String);
+ if (source instanceof byte[]) {
+ return source;
+ }
+ return ((String) source).getBytes(UTF_8);
+ }
+ }
+
+ @ValueSource(strings = {"red herring", "tH15_1S-4_53Cr3T.fl4Ga"})
+ @FuzzTest
+ void fuzzTheFlag(@ConvertWith(Utf8BytesConverter.class) byte[] bytes)
+ throws NoSuchAlgorithmException {
+ assumeTrue(bytes.length > 0);
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ digest.update(bytes, 0, bytes.length - 1);
+ byte[] hash = digest.digest();
+ byte secret = bytes[bytes.length - 1];
+ if (MessageDigest.isEqual(hash, FLAG_SHA256) && secret == 's') {
+ throw new Error("Fl4g 4nd s3cr3et f0und!");
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/JavaSeedFuzzTest.java b/examples/junit/src/test/java/com/example/JavaSeedFuzzTest.java
new file mode 100644
index 00000000..4f63e9a1
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/JavaSeedFuzzTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.example;
+
+import static java.util.Arrays.asList;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import com.code_intelligence.jazzer.mutation.annotation.NotNull;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class JavaSeedFuzzTest {
+ // Generated via:
+ // printf 'tH15_1S-4_53Cr3T.fl4G' | openssl dgst -binary -sha256 | openssl base64 -A
+ // Luckily the fuzzer can't read comments ;-)
+ private static final byte[] FLAG_SHA256 =
+ Base64.getDecoder().decode("q0vPdz5oeJIW3k2U4VJ+aWDufzzZbKAcevc9cNoUTSM=");
+
+ static Stream<Arguments> fuzzTheFlag() {
+ return Stream.of(arguments(asList("red", "herring"), 0),
+ // This argument passes the hash check, but does not trigger the finding right away. This
+ // is meant to verify that the seed ends up in the corpus, serving as the base for future
+ // mutations rather than just being executed once.
+ arguments(asList("tH15_1S", "-4_53Cr3T", ".fl4G"), 42));
+ }
+
+ @MethodSource
+ @FuzzTest
+ void fuzzTheFlag(@NotNull List<@NotNull String> flagParts, int secret)
+ throws NoSuchAlgorithmException {
+ byte[] hash = MessageDigest.getInstance("SHA-256").digest(
+ String.join("", flagParts).getBytes(StandardCharsets.UTF_8));
+ if (MessageDigest.isEqual(hash, FLAG_SHA256) && secret == 1337) {
+ throw new Error("Fl4g 4nd s3cr3et f0und!");
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/KeepGoingFuzzTest.java b/examples/junit/src/test/java/com/example/KeepGoingFuzzTest.java
new file mode 100644
index 00000000..ad5d09d2
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/KeepGoingFuzzTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.example;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+public class KeepGoingFuzzTest {
+ private static int counter = 0;
+
+ @FuzzTest
+ public void keepGoingFuzzTest(byte[] ignored) {
+ counter++;
+ if (counter == 1) {
+ throw new IllegalArgumentException("error1");
+ }
+ if (counter == 2) {
+ throw new IllegalArgumentException("error2");
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/LifecycleFuzzTest.java b/examples/junit/src/test/java/com/example/LifecycleFuzzTest.java
new file mode 100644
index 00000000..0d5dc2c7
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/LifecycleFuzzTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2022 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.example;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import java.io.IOException;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.TestInstancePostProcessor;
+
+@TestMethodOrder(MethodOrderer.MethodName.class)
+@ExtendWith(LifecycleFuzzTest.LifecycleInstancePostProcessor.class)
+class LifecycleFuzzTest {
+ // In fuzzing mode, the test is invoked once on the empty input and once with Jazzer.
+ private static final int EXPECTED_EACH_COUNT =
+ System.getenv().getOrDefault("JAZZER_FUZZ", "").isEmpty() ? 1 : 2;
+
+ private static int beforeAllCount = 0;
+ private static int beforeEachGlobalCount = 0;
+ private static int afterEachGlobalCount = 0;
+ private static int afterAllCount = 0;
+
+ private boolean beforeEachCalledOnInstance = false;
+ private boolean testInstancePostProcessorCalledOnInstance = false;
+
+ @BeforeAll
+ static void beforeAll() {
+ beforeAllCount++;
+ }
+
+ @BeforeEach
+ void beforeEach() {
+ beforeEachGlobalCount++;
+ beforeEachCalledOnInstance = true;
+ }
+
+ @Disabled
+ @FuzzTest
+ void disabledFuzz(byte[] data) {
+ throw new AssertionError("This test should not be executed");
+ }
+
+ @FuzzTest(maxDuration = "1s")
+ void lifecycleFuzz(byte[] data) {
+ Assertions.assertEquals(1, beforeAllCount);
+ Assertions.assertEquals(beforeEachGlobalCount, afterEachGlobalCount + 1);
+ Assertions.assertTrue(beforeEachCalledOnInstance);
+ Assertions.assertTrue(testInstancePostProcessorCalledOnInstance);
+ }
+
+ @AfterEach
+ void afterEach() {
+ afterEachGlobalCount++;
+ }
+
+ @AfterAll
+ static void afterAll() throws IOException {
+ afterAllCount++;
+ Assertions.assertEquals(1, beforeAllCount);
+ Assertions.assertEquals(EXPECTED_EACH_COUNT, beforeEachGlobalCount);
+ Assertions.assertEquals(EXPECTED_EACH_COUNT, afterEachGlobalCount);
+ Assertions.assertEquals(1, afterAllCount);
+ throw new IOException();
+ }
+
+ static class LifecycleInstancePostProcessor implements TestInstancePostProcessor {
+ @Override
+ public void postProcessTestInstance(Object o, ExtensionContext extensionContext) {
+ ((LifecycleFuzzTest) o).testInstancePostProcessorCalledOnInstance = true;
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/MockitoFuzzTest.java b/examples/junit/src/test/java/com/example/MockitoFuzzTest.java
new file mode 100644
index 00000000..c3c2e973
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/MockitoFuzzTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.example;
+
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import org.mockito.Mockito;
+
+public class MockitoFuzzTest {
+ public static class Foo {
+ public String bar(String ignored) {
+ return "bar";
+ }
+ }
+
+ @FuzzTest
+ void fuzzWithMockito(byte[] bytes) {
+ // Mock the Foo class to trigger an instrumentation cycle,
+ // if not properly ignored.
+ Foo foo = Mockito.mock(Foo.class);
+ foo.bar(new String(bytes));
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/MutatorFuzzTest.java b/examples/junit/src/test/java/com/example/MutatorFuzzTest.java
new file mode 100644
index 00000000..f3644791
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/MutatorFuzzTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.example;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.code_intelligence.jazzer.driver.FuzzTargetRunner;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import com.code_intelligence.jazzer.mutation.annotation.NotNull;
+import java.util.List;
+import org.junit.jupiter.api.AfterAll;
+
+class MutatorFuzzTest {
+ @FuzzTest
+ void mutatorFuzz(List<@NotNull String> list) {
+ // Check that the mutator is actually doing something.
+ if (list != null && list.size() > 3 && list.get(2).equals("mutator")) {
+ throw new AssertionError("Found expected JUnit mutator test issue");
+ }
+ }
+
+ @AfterAll
+ static void assertFuzzTargetRunner() {
+ // FuzzTargetRunner values are not set in JUnit engine tests.
+ String jazzerFuzz = System.getenv("JAZZER_FUZZ");
+ if (jazzerFuzz != null && !jazzerFuzz.isEmpty()) {
+ assertTrue(FuzzTargetRunner.invalidCorpusFilesPresent());
+ assertEquals(FuzzTargetRunner.mutatorDebugString(), "Arguments[Nullable<List<String>>]");
+ }
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/ThrowingFuzzTest.java b/examples/junit/src/test/java/com/example/ThrowingFuzzTest.java
new file mode 100644
index 00000000..eabfb85d
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/ThrowingFuzzTest.java
@@ -0,0 +1,25 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+
+public class ThrowingFuzzTest {
+ @FuzzTest
+ public void throwingFuzz(FuzzedDataProvider ignored) {
+ throw new IllegalStateException("This is a test.");
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/ValidFuzzTests.java b/examples/junit/src/test/java/com/example/ValidFuzzTests.java
new file mode 100644
index 00000000..465d3b7e
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/ValidFuzzTests.java
@@ -0,0 +1,76 @@
+// Copyright 2022 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.example;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+@SuppressWarnings("InvalidPatternSyntax")
+class ValidFuzzTests {
+ @FuzzTest
+ void dataFuzz(FuzzedDataProvider data) {
+ switch (data.consumeRemainingAsString()) {
+ case "no_crash":
+ return;
+ case "assert":
+ fail("JUnit assert failed");
+ case "honeypot":
+ try {
+ Class.forName("jaz.Zer").newInstance();
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ignored) {
+ // Ignored, but the honeypot class should still throw an exception.
+ }
+ case "sanitizer_internal_class":
+ try {
+ new ProcessBuilder("jazze").start();
+ } catch (IOException ignored) {
+ // Ignored, but the sanitizer should still throw an exception.
+ }
+ case "sanitizer_user_class":
+ try {
+ Pattern.compile("[");
+ } catch (Throwable ignored) {
+ // Ignored, but the JUnit test should report an error even though all throwables are
+ // caught - just like Jazzer would.
+ }
+ case "":
+ default:
+ throw new FuzzerSecurityIssueMedium();
+ }
+ }
+
+ @FuzzTest
+ void byteFuzz(byte[] data) {
+ if (data.length < 1) {
+ return;
+ }
+ if (data[0] % 2 == 0) {
+ fail();
+ }
+ }
+
+ @FuzzTest(maxDuration = "10s")
+ void noCrashFuzz(byte[] data) {
+ if (data.length < 10) {
+ return;
+ }
+ Parser.parse(data);
+ }
+}
diff --git a/examples/junit/src/test/java/com/example/ValueProfileFuzzTest.java b/examples/junit/src/test/java/com/example/ValueProfileFuzzTest.java
new file mode 100644
index 00000000..e69562f3
--- /dev/null
+++ b/examples/junit/src/test/java/com/example/ValueProfileFuzzTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium;
+import com.code_intelligence.jazzer.junit.FuzzTest;
+import java.util.Base64;
+
+class ValueProfileFuzzTest {
+ // Only passed with the configuration parameter jazzer.valueprofile=true.
+ @FuzzTest(maxDuration = "20s")
+ void valueProfileFuzz(byte[] data) {
+ // Trigger some coverage even with value profiling disabled.
+ if (data.length < 1 || data[0] > 100) {
+ return;
+ }
+ if (base64(data).equals("SmF6emVy")) {
+ throw new FuzzerSecurityIssueMedium();
+ }
+ }
+
+ private static String base64(byte[] input) {
+ return Base64.getEncoder().encodeToString(input);
+ }
+}
diff --git a/examples/junit/src/test/resources/BUILD.bazel b/examples/junit/src/test/resources/BUILD.bazel
new file mode 100644
index 00000000..69343053
--- /dev/null
+++ b/examples/junit/src/test/resources/BUILD.bazel
@@ -0,0 +1,11 @@
+java_library(
+ name = "example_seed_corpora",
+ resources = glob(["com/example/*Inputs/**"]),
+ visibility = ["//examples/junit/src/test/java/com/example:__pkg__"],
+)
+
+filegroup(
+ name = "MutatorFuzzTestInputs",
+ srcs = ["com/example/MutatorFuzzTestInputs"],
+ visibility = ["//visibility:public"],
+)
diff --git a/examples/junit/src/test/resources/com/example/AutofuzzWithCorpusFuzzTestInputs/autofuzzWithCorpus/crashing_input b/examples/junit/src/test/resources/com/example/AutofuzzWithCorpusFuzzTestInputs/autofuzzWithCorpus/crashing_input
new file mode 100644
index 00000000..2c92661f
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/AutofuzzWithCorpusFuzzTestInputs/autofuzzWithCorpus/crashing_input
Binary files differ
diff --git a/examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/fails b/examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/fails
new file mode 100644
index 00000000..63d8dbd4
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/fails
@@ -0,0 +1 @@
+b \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/succeeds b/examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/succeeds
new file mode 100644
index 00000000..2e65efe2
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ByteFuzzTestInputs/byteFuzz/succeeds
@@ -0,0 +1 @@
+a \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/MutatorFuzzTestInputs/mutatorFuzz/invalid b/examples/junit/src/test/resources/com/example/MutatorFuzzTestInputs/mutatorFuzz/invalid
new file mode 100644
index 00000000..acbe86c7
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/MutatorFuzzTestInputs/mutatorFuzz/invalid
@@ -0,0 +1 @@
+abcd
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/assert b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/assert
new file mode 100644
index 00000000..60d58a74
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/assert
@@ -0,0 +1 @@
+assert \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/honeypot b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/honeypot
new file mode 100644
index 00000000..ff56ae26
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/honeypot
@@ -0,0 +1 @@
+honeypot \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_internal_class b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_internal_class
new file mode 100644
index 00000000..05ead164
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_internal_class
@@ -0,0 +1 @@
+sanitizer_internal_class \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_user_class b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_user_class
new file mode 100644
index 00000000..067da781
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz/sanitizer_user_class
@@ -0,0 +1 @@
+sanitizer_user_class \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/assert b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/assert
new file mode 100644
index 00000000..60d58a74
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/assert
@@ -0,0 +1 @@
+assert \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/honeypot b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/honeypot
new file mode 100644
index 00000000..ff56ae26
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/honeypot
@@ -0,0 +1 @@
+honeypot \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_internal_class b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_internal_class
new file mode 100644
index 00000000..05ead164
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_internal_class
@@ -0,0 +1 @@
+sanitizer_internal_class \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_user_class b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_user_class
new file mode 100644
index 00000000..067da781
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/dataFuzz/sanitizer_user_class
@@ -0,0 +1 @@
+sanitizer_user_class \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/assert b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/assert
new file mode 100644
index 00000000..60d58a74
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/assert
@@ -0,0 +1 @@
+assert \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/honeypot b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/honeypot
new file mode 100644
index 00000000..ff56ae26
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/honeypot
@@ -0,0 +1 @@
+honeypot \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_internal_class b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_internal_class
new file mode 100644
index 00000000..05ead164
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_internal_class
@@ -0,0 +1 @@
+sanitizer_internal_class \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_user_class b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_user_class
new file mode 100644
index 00000000..067da781
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/noCrashFuzz/sanitizer_user_class
@@ -0,0 +1 @@
+sanitizer_user_class \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/no_crash b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/no_crash
new file mode 100644
index 00000000..65435580
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValidFuzzTestsInputs/no_crash
@@ -0,0 +1 @@
+no_crash \ No newline at end of file
diff --git a/examples/junit/src/test/resources/com/example/ValueProfileFuzzTestInputs/valueProfileFuzz/empty_seed b/examples/junit/src/test/resources/com/example/ValueProfileFuzzTestInputs/valueProfileFuzz/empty_seed
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/examples/junit/src/test/resources/com/example/ValueProfileFuzzTestInputs/valueProfileFuzz/empty_seed
diff --git a/examples/junit/src/test/resources/junit-platform.properties b/examples/junit/src/test/resources/junit-platform.properties
new file mode 100644
index 00000000..02290619
--- /dev/null
+++ b/examples/junit/src/test/resources/junit-platform.properties
@@ -0,0 +1 @@
+jazzer.instrument=com.example.**,com.other.package.**
diff --git a/examples/src/main/java/com/example/BatikTranscoderFuzzer.java b/examples/src/main/java/com/example/BatikTranscoderFuzzer.java
new file mode 100644
index 00000000..cdd22163
--- /dev/null
+++ b/examples/src/main/java/com/example/BatikTranscoderFuzzer.java
@@ -0,0 +1,44 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import java.io.*;
+import org.apache.batik.transcoder.TranscoderException;
+import org.apache.batik.transcoder.TranscoderInput;
+import org.apache.batik.transcoder.TranscoderOutput;
+import org.apache.batik.transcoder.image.JPEGTranscoder;
+
+public class BatikTranscoderFuzzer {
+ public static void fuzzerTestOneInput(FuzzedDataProvider data) throws IOException {
+ String host = data.consumeRemainingAsString();
+
+ byte[] svg =
+ ("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" >\n"
+ + "<image width=\"50\" height=\"50\" xlink:href=\"https://" + host + "/\"></image>\n"
+ + "</svg>")
+ .getBytes();
+
+ // Convert SVG to JPEG
+ try {
+ JPEGTranscoder transcoder = new JPEGTranscoder();
+ TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svg));
+ TranscoderOutput output = new TranscoderOutput(new ByteArrayOutputStream());
+ transcoder.transcode(input, output);
+ } catch (TranscoderException | IllegalArgumentException e) {
+ // Ignored
+ }
+ }
+}
diff --git a/examples/src/main/java/com/example/CommonsTextFuzzer.java b/examples/src/main/java/com/example/CommonsTextFuzzer.java
new file mode 100644
index 00000000..32b309d5
--- /dev/null
+++ b/examples/src/main/java/com/example/CommonsTextFuzzer.java
@@ -0,0 +1,28 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import org.apache.commons.text.StringSubstitutor;
+
+public class CommonsTextFuzzer {
+ public static void fuzzerTestOneInput(FuzzedDataProvider data) {
+ try {
+ StringSubstitutor.createInterpolator().replace(data.consumeAsciiString(20));
+ } catch (
+ java.lang.IllegalArgumentException | java.lang.ArrayIndexOutOfBoundsException ignored) {
+ }
+ }
+}
diff --git a/examples/src/main/java/com/example/ExampleFuzzerWithNative.java b/examples/src/main/java/com/example/ExampleFuzzerWithNative.java
index b9a13e24..90639deb 100644
--- a/examples/src/main/java/com/example/ExampleFuzzerWithNative.java
+++ b/examples/src/main/java/com/example/ExampleFuzzerWithNative.java
@@ -19,7 +19,7 @@ import com.github.fmeum.rules_jni.RulesJni;
public class ExampleFuzzerWithNative {
static {
- String native_lib = System.getProperty("jazzer.native_lib");
+ String native_lib = System.getenv("EXAMPLE_NATIVE_LIB");
RulesJni.loadLibrary(native_lib, ExampleFuzzerWithNative.class);
}
diff --git a/examples/src/main/java/com/example/ExampleKotlinFuzzer.kt b/examples/src/main/java/com/example/ExampleKotlinFuzzer.kt
new file mode 100644
index 00000000..eb1aea8f
--- /dev/null
+++ b/examples/src/main/java/com/example/ExampleKotlinFuzzer.kt
@@ -0,0 +1,38 @@
+// Copyright 2022 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.example
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider
+import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium
+
+object ExampleKotlinFuzzer {
+
+ @JvmStatic
+ fun fuzzerTestOneInput(data: FuzzedDataProvider) {
+ exploreMe(data.consumeString(8), data.consumeInt(), data.consumeRemainingAsString())
+ }
+
+ private fun exploreMe(prefix: String, n: Int, suffix: String) {
+ if (prefix.findAnyOf(arrayListOf("Fuzz", "Test")) != null) {
+ if (n >= 2000000) {
+ if (suffix.startsWith("@")) {
+ if (suffix.substring(1) == "Jazzer") {
+ throw FuzzerSecurityIssueMedium("Jazzer resolved string comparisons in Kotlin")
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt b/examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt
new file mode 100644
index 00000000..c86824e8
--- /dev/null
+++ b/examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt
@@ -0,0 +1,37 @@
+// 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.example
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider
+import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium
+
+object ExampleKotlinValueProfileFuzzer {
+
+ @JvmStatic
+ fun fuzzerTestOneInput(data: FuzzedDataProvider) {
+ if (data.consumeInt().compareTo(0x11223344) != 0) {
+ return
+ }
+ if (encrypt(data.consumeLong()).compareTo(5788627691251634856) == 0 &&
+ encrypt(data.consumeLong()).compareTo(6293579535917519017) == 0
+ ) {
+ throw FuzzerSecurityIssueMedium("Jazzer can handle integral comparisons in Kotlin")
+ }
+ }
+
+ private fun encrypt(n: Long): Long {
+ return n.xor(0x1122334455667788)
+ }
+}
diff --git a/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java b/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java
index d704da39..494bff16 100644
--- a/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java
+++ b/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java
@@ -14,15 +14,13 @@
package com.example;
-import java.util.ArrayList;
-
public class ExampleOutOfMemoryFuzzer {
+ public static long[] leak;
+
public static void fuzzerTestOneInput(byte[] input) {
- ArrayList<Byte> bytes = new ArrayList<>();
- int pos = 0;
- while (pos >= 0 && pos < input.length) {
- bytes.add(input[pos]);
- pos += input[pos] + 1;
+ if (input.length == 0) {
+ return;
}
+ leak = new long[Integer.MAX_VALUE];
}
}
diff --git a/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java b/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java
index b027de5b..109db94e 100644
--- a/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java
+++ b/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java
@@ -24,6 +24,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
public class ExamplePathTraversalFuzzerHooks {
+ private static final String publicFilesRootPath = "/app/upload/";
+
@MethodHook(type = HookType.BEFORE, targetClassName = "java.io.File", targetMethod = "<init>",
targetMethodDescriptor = "(Ljava/lang/String;)V")
public static void
@@ -36,7 +38,7 @@ public class ExamplePathTraversalFuzzerHooks {
// Invalid paths are correctly rejected by the application.
return;
}
- if (!normalizedPath.startsWith(ExamplePathTraversalFuzzer.publicFilesRootPath)) {
+ if (!normalizedPath.startsWith(publicFilesRootPath)) {
// Simply throwing an exception from here would not work as the calling code catches and
// ignores all Throwables. Instead, use the Jazzer API to report a finding from a hook.
Jazzer.reportFindingFromHook(new FuzzerSecurityIssueHigh(
diff --git a/examples/src/main/java/com/example/MazeFuzzer.java b/examples/src/main/java/com/example/MazeFuzzer.java
index 9d3448c7..beab610e 100644
--- a/examples/src/main/java/com/example/MazeFuzzer.java
+++ b/examples/src/main/java/com/example/MazeFuzzer.java
@@ -17,6 +17,7 @@ package com.example;
import com.code_intelligence.jazzer.api.Consumer3;
import com.code_intelligence.jazzer.api.Jazzer;
import java.util.Arrays;
+import java.util.Objects;
import java.util.stream.Collectors;
// A fuzz target that shows how manually informing the fuzzer about important state can make a fuzz
@@ -60,7 +61,7 @@ public final class MazeFuzzer {
// This is the key line that makes this fuzz target work: It instructs the fuzzer to track
// every new combination of x and y as a new feature. Without it, the fuzzer would be
// completely lost in the maze as guessing an escaping path by chance is close to impossible.
- Jazzer.exploreState(hash(x, y), 0);
+ Jazzer.exploreState((byte) Objects.hash(x, y), 0);
if (REACHED_FIELDS[y][x] == ' ') {
// Fuzzer reached a new field in the maze, print its progress.
REACHED_FIELDS[y][x] = '.';
@@ -69,18 +70,6 @@ public final class MazeFuzzer {
});
}
- // Hash function with good mixing properties published by Thomas Mueller
- // under the terms of CC BY-SA 4.0 at
- // https://stackoverflow.com/a/12996028
- // https://creativecommons.org/licenses/by-sa/4.0/
- private static byte hash(byte x, byte y) {
- int h = (x << 8) | y;
- h = ((h >> 16) ^ h) * 0x45d9f3b;
- h = ((h >> 16) ^ h) * 0x45d9f3b;
- h = (h >> 16) ^ h;
- return (byte) h;
- }
-
private static class TreasureFoundException extends RuntimeException {
TreasureFoundException(byte[] commands) {
super(renderPath(commands));
diff --git a/examples/src/main/native/com/example/BUILD.bazel b/examples/src/main/native/com/example/BUILD.bazel
index 4c44327a..338be9ee 100644
--- a/examples/src/main/native/com/example/BUILD.bazel
+++ b/examples/src/main/native/com/example/BUILD.bazel
@@ -17,13 +17,14 @@ cc_jni_library(
"_DISABLE_VECTOR_ANNOTATION=1",
],
linkopts = select({
- "//:clang_on_linux": ["-fuse-ld=lld"],
"@platforms//os:windows": [
# Windows requires all symbols that should be imported from the main
# executable to be defined by an import lib.
"/wholearchive:clang_rt.asan_dll_thunk-x86_64.lib",
],
- "//conditions:default": [],
+ "//conditions:default": [
+ "-fsanitize=fuzzer-no-link,address",
+ ],
}),
visibility = ["//examples:__pkg__"],
deps = [
@@ -41,13 +42,14 @@ cc_jni_library(
"-fno-sanitize-recover=all",
],
linkopts = select({
- "//:clang_on_linux": ["-fuse-ld=lld"],
"@platforms//os:windows": [
# Using the asan thunk is correct here as it contains symbols for
# UBSan and SanCov as well.
"/wholearchive:clang_rt.asan_dll_thunk-x86_64.lib",
],
- "//conditions:default": [],
+ "//conditions:default": [
+ "-fsanitize=fuzzer-no-link,undefined",
+ ],
}),
visibility = ["//examples:__pkg__"],
deps = [
diff --git a/examples/src/main/native/com/example/com_example_ExampleFuzzerWithNative.cpp b/examples/src/main/native/com/example/com_example_ExampleFuzzerWithNative.cpp
index 774e5998..971ea740 100644
--- a/examples/src/main/native/com/example/com_example_ExampleFuzzerWithNative.cpp
+++ b/examples/src/main/native/com/example/com_example_ExampleFuzzerWithNative.cpp
@@ -14,6 +14,7 @@
#include "com_example_ExampleFuzzerWithNative.h"
+#include <cstring>
#include <limits>
#include <string>
@@ -27,8 +28,10 @@ __attribute__((optnone)) void parseInternal(const std::string &input) {
}
if (input[0] == 'a' && input[1] == 'b' && input[5] == 'c') {
if (input.find("secret_in_native_library") != std::string::npos) {
- // Crashes with ASan.
- [[maybe_unused]] char foo = input[input.size() + 2];
+ // Crashes with ASan, whose use-after-free hooks detect
+ const char *mem = static_cast<const char *>(malloc(2));
+ free((void *)mem);
+ [[maybe_unused]] bool foo = memcmp(mem, mem + 1, 1);
}
}
}