diff --git a/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java b/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java index ee30fb534..7537a7fd8 100644 --- a/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java +++ b/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java @@ -112,7 +112,12 @@ public static FuzzTestExecutor prepare(ExtensionContext context, String maxDurat && corpusFilesOrDirs.stream().map(Paths::get).allMatch(Files::isRegularFile)) { javaSeedsDir = Optional.empty(); } else { - javaSeedsDir = Optional.of(addInputAndSeedDirs(context, libFuzzerArgs)); + // Only create the default generated corpus directory if it is used as the generated corpus + // directory, i.e., if the user didn't provide any custom corpus directories that come before + // it on the libFuzzer command line. + boolean createDefaultGeneratedCorpusDir = corpusFilesOrDirs.isEmpty(); + javaSeedsDir = + Optional.of(addInputAndSeedDirs(context, libFuzzerArgs, createDefaultGeneratedCorpusDir)); } libFuzzerArgs.add("-max_total_time=" + durationStringToSeconds(maxDuration)); @@ -169,7 +174,8 @@ private static Optional translateJUnitTimeoutToLibFuzzerFlag(ExtensionCo * * @return the temporary Java seed corpus directory */ - private static Path addInputAndSeedDirs(ExtensionContext context, List libFuzzerArgs) + private static Path addInputAndSeedDirs( + ExtensionContext context, List libFuzzerArgs, boolean createDefaultGeneratedCorpusDir) throws IOException { Class fuzzTestClass = context.getRequiredTestClass(); Method fuzzTestMethod = context.getRequiredTestMethod(); @@ -184,20 +190,25 @@ private static Path addInputAndSeedDirs(ExtensionContext context, List l // The path is specified relative to the current working directory, which with JUnit is the // project directory. Path generatedCorpusDir = baseDir.resolve(generatedCorpusPath(fuzzTestClass, fuzzTestMethod)); - Files.createDirectories(generatedCorpusDir); - String absoluteCorpusDir = generatedCorpusDir.toAbsolutePath().toString(); - - // Even if support for long paths (+260 characters) is enabled on Windows, - // libFuzzer does not work properly. This can be circumvented by prepending "\\?\" to the path, - // see: - // https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry - // Error message: "GetFileAttributesA() failed for (Error code: 3)." - // https://github.com/llvm/llvm-project/blob/release/17.x/compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp#L65 - if (Utils.isWindows()) { - absoluteCorpusDir = "\\\\?\\" + absoluteCorpusDir; + if (createDefaultGeneratedCorpusDir) { + Files.createDirectories(generatedCorpusDir); } + if (Files.exists(generatedCorpusDir)) { + String absoluteCorpusDir = generatedCorpusDir.toAbsolutePath().toString(); + + // Even if support for long paths (+260 characters) is enabled on Windows, + // libFuzzer does not work properly. This can be circumvented by prepending "\\?\" to the + // path, + // see: + // https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry + // Error message: "GetFileAttributesA() failed for (Error code: 3)." + // https://github.com/llvm/llvm-project/blob/release/17.x/compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp#L65 + if (Utils.isWindows()) { + absoluteCorpusDir = "\\\\?\\" + absoluteCorpusDir; + } - libFuzzerArgs.add(absoluteCorpusDir); + libFuzzerArgs.add(absoluteCorpusDir); + } // We can only emit findings into the source tree version of the inputs directory, not e.g. the // copy under Maven's target directory. If it doesn't exist, collect the inputs in the current diff --git a/src/test/java/com/code_intelligence/jazzer/junit/CorpusDirectoryTest.java b/src/test/java/com/code_intelligence/jazzer/junit/CorpusDirectoryTest.java index b8ea85f58..42476b4ed 100644 --- a/src/test/java/com/code_intelligence/jazzer/junit/CorpusDirectoryTest.java +++ b/src/test/java/com/code_intelligence/jazzer/junit/CorpusDirectoryTest.java @@ -158,11 +158,11 @@ public void fuzzingEnabled() throws IOException { assertCrashFileExistsIn(artifactsDirectory); assertNoCrashFileExistsIn(baseDir); assertNoCrashFileExistsIn(explicitGeneratedCorpus); - assertNoCrashFileExistsIn(defaultGeneratedCorpus); + // Default generated corpus directory isn't used and thus should not have been created. + assertThat(Files.notExists(defaultGeneratedCorpus)).isTrue(); // Verify that corpus files are written to given corpus directory and not generated one. assertThat(Files.list(explicitGeneratedCorpus)).isNotEmpty(); - assertThat(Files.list(defaultGeneratedCorpus)).isEmpty(); } @Test