Skip to content
New issue

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

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

Already on GitHub? # to your account

Add check subcommand to perform a cargo check #317

Merged
merged 1 commit into from
Jul 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ enum Command {
/// Build fuzz targets
Build(options::Build),

#[structopt(template(LONG_ABOUT_TEMPLATE))]
/// Type-check the fuzz targets
Check(options::Check),

/// Print the `std::fmt::Debug` output for an input
Fmt(options::Fmt),

Expand Down Expand Up @@ -146,6 +150,7 @@ impl RunCommand for Command {
Command::Init(x) => x.run_command(),
Command::Add(x) => x.run_command(),
Command::Build(x) => x.run_command(),
Command::Check(x) => x.run_command(),
Command::List(x) => x.run_command(),
Command::Fmt(x) => x.run_command(),
Command::Run(x) => x.run_command(),
Expand Down
11 changes: 9 additions & 2 deletions src/options.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod add;
mod build;
mod check;
mod cmin;
mod coverage;
mod fmt;
Expand All @@ -9,8 +10,8 @@ mod run;
mod tmin;

pub use self::{
add::Add, build::Build, cmin::Cmin, coverage::Coverage, fmt::Fmt, init::Init, list::List,
run::Run, tmin::Tmin,
add::Add, build::Build, check::Check, cmin::Cmin, coverage::Coverage, fmt::Fmt, init::Init,
list::List, run::Run, tmin::Tmin,
};

use std::str::FromStr;
Expand Down Expand Up @@ -57,6 +58,12 @@ impl FromStr for Sanitizer {
}
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BuildMode {
Build,
Check,
}

#[derive(Clone, Debug, StructOpt, PartialEq)]
pub struct BuildOptions {
#[structopt(short = "D", long = "dev", conflicts_with = "release")]
Expand Down
8 changes: 6 additions & 2 deletions src/options/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
options::{BuildOptions, FuzzDirWrapper},
options::{BuildMode, BuildOptions, FuzzDirWrapper},
project::FuzzProject,
RunCommand,
};
Expand All @@ -21,6 +21,10 @@ pub struct Build {
impl RunCommand for Build {
fn run_command(&mut self) -> Result<()> {
let project = FuzzProject::new(self.fuzz_dir_wrapper.fuzz_dir.to_owned())?;
project.exec_build(&self.build, self.target.as_deref().map(|s| s))
project.exec_build(
BuildMode::Build,
&self.build,
self.target.as_deref().map(|s| s),
)
}
}
30 changes: 30 additions & 0 deletions src/options/check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use crate::{
options::{BuildMode, BuildOptions, FuzzDirWrapper},
project::FuzzProject,
RunCommand,
};
use anyhow::Result;
use structopt::StructOpt;

#[derive(Clone, Debug, StructOpt)]
pub struct Check {
#[structopt(flatten)]
pub build: BuildOptions,

#[structopt(flatten)]
pub fuzz_dir_wrapper: FuzzDirWrapper,

/// Name of the fuzz target to check, or check all targets if not supplied
pub target: Option<String>,
}

impl RunCommand for Check {
fn run_command(&mut self) -> Result<()> {
let project = FuzzProject::new(self.fuzz_dir_wrapper.fuzz_dir.to_owned())?;
project.exec_build(
BuildMode::Check,
&self.build,
self.target.as_deref().map(|s| s),
)
}
}
17 changes: 11 additions & 6 deletions src/project.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::options::{self, BuildOptions, Sanitizer};
use crate::options::{self, BuildMode, BuildOptions, Sanitizer};
use crate::utils::default_target;
use anyhow::{anyhow, bail, Context, Result};
use std::collections::HashSet;
Expand Down Expand Up @@ -268,10 +268,15 @@ impl FuzzProject {

pub fn exec_build(
&self,
mode: options::BuildMode,
build: &options::BuildOptions,
fuzz_target: Option<&str>,
) -> Result<()> {
let mut cmd = self.cargo("build", build)?;
let cargo_subcommand = match mode {
options::BuildMode::Build => "build",
options::BuildMode::Check => "check",
};
let mut cmd = self.cargo(cargo_subcommand, build)?;

if let Some(fuzz_target) = fuzz_target {
cmd.arg("--bin").arg(fuzz_target);
Expand Down Expand Up @@ -408,7 +413,7 @@ impl FuzzProject {

/// Fuzz a given fuzz target
pub fn exec_fuzz(&self, run: &options::Run) -> Result<()> {
self.exec_build(&run.build, Some(&run.target))?;
self.exec_build(BuildMode::Build, &run.build, Some(&run.target))?;
let mut cmd = self.cargo_run(&run.build, &run.target)?;

for arg in &run.args {
Expand Down Expand Up @@ -497,7 +502,7 @@ impl FuzzProject {
}

pub fn exec_tmin(&self, tmin: &options::Tmin) -> Result<()> {
self.exec_build(&tmin.build, Some(&tmin.target))?;
self.exec_build(BuildMode::Build, &tmin.build, Some(&tmin.target))?;
let mut cmd = self.cargo_run(&tmin.build, &tmin.target)?;
cmd.arg("-minimize_crash=1")
.arg(format!("-runs={}", tmin.runs))
Expand Down Expand Up @@ -572,7 +577,7 @@ impl FuzzProject {
}

pub fn exec_cmin(&self, cmin: &options::Cmin) -> Result<()> {
self.exec_build(&cmin.build, Some(&cmin.target))?;
self.exec_build(BuildMode::Build, &cmin.build, Some(&cmin.target))?;
let mut cmd = self.cargo_run(&cmin.build, &cmin.target)?;

for arg in &cmin.args {
Expand Down Expand Up @@ -613,7 +618,7 @@ impl FuzzProject {
/// Produce coverage information for a given corpus
pub fn exec_coverage(self, coverage: &options::Coverage) -> Result<()> {
// Build project with source-based coverage generation enabled.
self.exec_build(&coverage.build, Some(&coverage.target))?;
self.exec_build(BuildMode::Build, &coverage.build, Some(&coverage.target))?;

// Retrieve corpus directories.
let corpora = if coverage.corpus.is_empty() {
Expand Down