Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: redesign arg parsing with structopt #52

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ maintenance = { status = "actively-developed" }

[dependencies]
arbitrary = "1"
structopt = "0.3"

[dev-dependencies]
rand = "0.8"
Expand Down
75 changes: 74 additions & 1 deletion src/bin/cargo-hfuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,77 @@ const HONGGFUZZ_WORKSPACE: &str = "hfuzz_workspace";
#[cfg(target_family="windows")]
compile_error!("honggfuzz-rs does not currently support Windows but works well under WSL (Windows Subsystem for Linux)");

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(name = "cargo-hfuzz", about = "Fuzz your Rust code with Google-developed Honggfuzz !")]
struct Opt {
#[structopt(subcommand)]
command: OptSub,
}

#[derive(Debug, StructOpt)]
struct CommonOpts {
/// only build binary but don't execute it
#[structopt(long)]
only_build: bool,

/// flags given to `rustc`, for example "-Z sanitizer=address"
#[structopt(long, env = "RUSTFLAGS")]
rustflags: Option<String>,

/// args given to `cargo build`
#[structopt(long, env = "HFUZZ_BUILD_ARGS")]
build_args: Option<String>,

/// path to working directory
#[structopt(short, long, default_value = "hfuzz_workspace", env = "HFUZZ_WORKSPACE")]
workspace: String,
}

#[derive(Debug, StructOpt)]
enum OptSub {
/// build and run fuzzing
Fuzz {
#[structopt(flatten)]
common_opts: CommonOpts,

/// path to fuzzer's input files (aka "corpus"), relative to `$HFUZZ_WORKSPACE/{TARGET}`
#[structopt(short, long, default_value = "input", env = "HFUZZ_INPUT")]
input: String,

/// which binary target to fuzz
target: String,
Copy link
Contributor

@drahnr drahnr Apr 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be in favour of changing this to --bin, since target is rather ambiguous with cargo having --target <TRIPLE>... Build for the target triple.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, target is indeed confusing.
however, as of now, this is not an optional argument (a la --bin), but we could rename it as binary and it would be reflected in the help messages.
WDYT?


/// do no build with compiler instrumentation
#[structopt(long)]
no_instr: bool,

/// args to target -- args to fuzzer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provides additional arguments to the underlying honggfuzz binary. See [honggfuzz usage](https//..) for details.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right now, the rightmost args given on the command line are forwarded to the fuzzed binary (child).
that's why to give args to the fuzzer (parent), it is currently needed to put them in an ENV var.

To keep that functionality, I wanted to introduce using -- as a way to separate the two kinds of args.

But maybe, the args to the fuzzed binary are not often used, if ever. Maybe it could be sacrificed in order to make things simpler.

/// ( https://github.com/google/honggfuzz/blob/master/docs/USAGE.md )
args: Vec<String>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to have a few additional options here, that provide convenience i.e. --iterations=<N> and --exit-on-crash=<code> - these are very common for CI usage, so shortcuts are a nicety :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your point, with this new code, those args could be put directly on the command line as you want.

Their documentation is from the upstream honggfuzz binary though...
I'll try to make it easy to access this help from the wrapper.

Maybe something like cargo hfuzz help inner-fuzzer would display the result of honggfuzz -h

},

Debug {
#[structopt(flatten)]
common_opts: CommonOpts,

/// name or path to debugger, like `rust-gdb`, `gdb`, `/usr/bin/lldb-7`..
#[structopt(short, long, default_value = "rust-lldb", env = "HFUZZ_DEBUGGER")]
debugger: String,

/// which binary target to fuzz
target: String,

/// path to crash file, typically like `hfuzz_workspace/[TARGET]/[..].fuzz`
crash_file: PathBuf,

/// args to target
target_args: Vec<String>,
},
Clean,
}

#[derive(PartialEq)]
enum BuildType {
ReleaseInstrumented,
Expand Down Expand Up @@ -252,7 +323,9 @@ fn hfuzz_clean<T>(args: T) where T: std::iter::Iterator<Item=String> {
}

fn main() {
// TODO: maybe use `clap` crate
let opt = Opt::from_args();
println!("{:?}", opt);
return; // WIP

let mut args = env::args().skip(1);
if args.next() != Some("hfuzz".to_string()) {
Expand Down