}
Inputs = new std::vector<std::string>;
for (size_t A = 1; A < Args.size(); A++) {
- if (ParseOneFlag(Args[A].c_str())) continue;
+ if (ParseOneFlag(Args[A].c_str())) {
+ if (Flags.ignore_remaining_args)
+ break;
+ continue;
+ }
Inputs->push_back(Args[A]);
}
}
exit(1);
}
std::string InputFilePath = Inputs->at(0);
- std::string BaseCmd =
- CloneArgsWithoutX(Args, "minimize_crash", "exact_artifact_path");
- auto InputPos = BaseCmd.find(" " + InputFilePath + " ");
+ auto BaseCmd = SplitBefore(
+ "-ignore_remaining_args=1",
+ CloneArgsWithoutX(Args, "minimize_crash", "exact_artifact_path"));
+ auto InputPos = BaseCmd.first.find(" " + InputFilePath + " ");
assert(InputPos != std::string::npos);
- BaseCmd.erase(InputPos, InputFilePath.size() + 1);
+ BaseCmd.first.erase(InputPos, InputFilePath.size() + 1);
if (Flags.runs <= 0 && Flags.max_total_time == 0) {
Printf("INFO: you need to specify -runs=N or "
"-max_total_time=N with -minimize_crash=1\n"
"INFO: defaulting to -max_total_time=600\n");
- BaseCmd += " -max_total_time=600";
+ BaseCmd.first += " -max_total_time=600";
}
auto LogFilePath = DirPlusFile(
Printf("CRASH_MIN: minimizing crash input: '%s' (%zd bytes)\n",
CurrentFilePath.c_str(), U.size());
- auto Cmd = BaseCmd + " " + CurrentFilePath + LogFileRedirect;
+ auto Cmd = BaseCmd.first + " " + CurrentFilePath + LogFileRedirect + " " +
+ BaseCmd.second;
Printf("CRASH_MIN: executing: %s\n", Cmd.c_str());
int ExitCode = ExecuteCommand(Cmd);
FUZZER_FLAG_STRING(exit_on_item, "Exit if an item with a given sha1 sum"
" was added to the corpus. "
"Used primarily for testing libFuzzer itself.")
+FUZZER_FLAG_INT(ignore_remaining_args, 0, "If 1, ignore all arguments passed "
+ "after this one. Useful for fuzzers that need to do their own "
+ "argument parsing.")
FUZZER_FLAG_STRING(run_equivalence_server, "Experimental")
FUZZER_FLAG_STRING(use_equivalence_server, "Experimental")
// Execute the inner process untill it passes.
// Every inner process should execute at least one input.
- std::string BaseCmd = CloneArgsWithoutX(Args, "keep-all-flags");
+ auto BaseCmd = SplitBefore("-ignore_remaining_args=1",
+ CloneArgsWithoutX(Args, "keep-all-flags"));
bool Success = false;
for (size_t i = 1; i <= AllFiles.size(); i++) {
Printf("MERGE-OUTER: attempt %zd\n", i);
- auto ExitCode =
- ExecuteCommand(BaseCmd + " -merge_control_file=" + CFPath);
+ auto ExitCode = ExecuteCommand(BaseCmd.first + " -merge_control_file=" +
+ CFPath + " " + BaseCmd.second);
if (!ExitCode) {
Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", i);
Success = true;
return CloneArgsWithoutX(Args, X, X);
}
+inline std::pair<std::string, std::string> SplitBefore(std::string X,
+ std::string S) {
+ auto Pos = S.find(X);
+ if (Pos == std::string::npos)
+ return std::make_pair(S, "");
+ return std::make_pair(S.substr(0, Pos), S.substr(Pos));
+}
+
std::string DisassembleCmd(const std::string &FileName);
std::string SearchRegexCmd(const std::string &Regex);
EmptyTest
EquivalenceATest
EquivalenceBTest
+ FlagsTest
FourIndependentBranchesTest
FullCoverageSetTest
InitializeTest
--- /dev/null
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Parse some flags
+#include <string>
+#include <vector>
+
+static std::vector<std::string> Flags;
+
+extern "C" int LLVMFuzzerInitialize(int *Argc, char ***Argv) {
+ // Parse --flags and anything after -ignore_remaining_args=1 is passed.
+ int I = 1;
+ while (I < *Argc) {
+ std::string S((*Argv)[I++]);
+ if (S == "-ignore_remaining_args=1")
+ break;
+ if (S.substr(0, 2) == "--")
+ Flags.push_back(S);
+ }
+ while (I < *Argc)
+ Flags.push_back(std::string((*Argv)[I++]));
+
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ fprintf(stderr, "BINGO ");
+ for (auto Flag : Flags)
+ fprintf(stderr, "%s ", Flag.c_str());
+ fprintf(stderr, "\n");
+ exit(0);
+}
-RUN: LLVMFuzzer-SimpleTest -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
+RUN: LLVMFuzzer-FlagsTest -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
FOO_BAR: WARNING: unrecognized flag '-foo_bar=1'; use -help=1 to list all flags
FOO_BAR: BINGO
-RUN: LLVMFuzzer-SimpleTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
+RUN: LLVMFuzzer-FlagsTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
DASH_DASH: WARNING: did you mean '-max_len=100' (single dash)?
DASH_DASH: INFO: A corpus is not provided, starting from an empty corpus
-RUN: LLVMFuzzer-SimpleTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL
+RUN: LLVMFuzzer-FlagsTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL
NO_INTERNAL-NOT: internal flag
+
+RUN: LLVMFuzzer-FlagsTest --foo-bar -runs=10 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU
+PASSTHRU: BINGO --foo-bar --baz -help=1 test
+
+RUN: mkdir -p %t/T0 %t/T1
+RUN: touch %t/T1/empty
+RUN: LLVMFuzzer-FlagsTest --foo-bar -merge=1 %t/T0 %t/T1 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU-MERGE
+PASSTHRU-MERGE: BINGO --foo-bar --baz -help=1 test