diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index 8f6a932c87..3706953d29 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -32,15 +32,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.51" @@ -122,17 +113,6 @@ dependencies = [ "log", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -266,25 +246,21 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.59.1" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" dependencies = [ "bitflags", "cexpr", "clang-sys", - "clap 2.34.0", - "env_logger 0.8.4", "lazy_static", "lazycell", - "log", "peeking_take_while", "proc-macro2 1.0.47", "quote 1.0.9", "regex", "rustc-hash", "shlex", - "which", ] [[package]] @@ -293,28 +269,16 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitvec" -version = "0.19.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" -dependencies = [ - "funty 1.1.0", - "radium 0.5.3", - "tap", - "wyz 0.2.0", -] - [[package]] name = "bitvec" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" dependencies = [ - "funty 2.0.0", - "radium 0.7.0", + "funty", + "radium", "tap", - "wyz 0.5.0", + "wyz", ] [[package]] @@ -376,11 +340,11 @@ checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" [[package]] name = "cexpr" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom 6.1.2", + "nom 7.1.0", ] [[package]] @@ -421,86 +385,32 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap" -version = "3.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d20de3739b4fb45a17837824f40aa1769cc7655d7a83e68739a77fe7b30c87a" -dependencies = [ - "atty", - "bitflags", - "clap_derive 3.2.4", - "clap_lex 0.2.2", - "indexmap", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap 0.15.0", -] - -[[package]] -name = "clap" -version = "4.0.26" +version = "4.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" +checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" dependencies = [ - "atty", "bitflags", - "clap_derive 4.0.21", - "clap_lex 0.3.0", + "clap_derive", + "clap_lex", + "is-terminal", "once_cell", - "strsim 0.10.0", + "strsim", "termcolor", ] [[package]] name = "clap_derive" -version = "3.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "026baf08b89ffbd332836002ec9378ef0e69648cbfadd68af7cd398ca5bf98f7" -dependencies = [ - "heck 0.4.0", - "proc-macro-error", - "proc-macro2 1.0.47", - "quote 1.0.9", - "syn 1.0.103", -] - -[[package]] -name = "clap_derive" -version = "4.0.21" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" dependencies = [ - "heck 0.4.0", + "heck", "proc-macro-error", "proc-macro2 1.0.47", "quote 1.0.9", "syn 1.0.103", ] -[[package]] -name = "clap_lex" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "clap_lex" version = "0.3.0" @@ -559,11 +469,11 @@ name = "coverage" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.0.26", + "clap", "cobertura", "debuggable-module", "debugger", - "env_logger 0.10.0", + "env_logger", "iced-x86", "log", "pete", @@ -753,7 +663,7 @@ name = "debuggable-module" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.0.26", + "clap", "elsa", "gimli", "goblin 0.6.0", @@ -853,10 +763,10 @@ name = "dynamic-library" version = "0.1.0" dependencies = [ "anyhow", + "clap", "debugger", "lazy_static", "regex", - "structopt", "thiserror", "winapi", "winreg 0.10.1", @@ -895,32 +805,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "env_logger" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.10.0" @@ -1078,12 +962,6 @@ dependencies = [ "libc", ] -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - [[package]] name = "funty" version = "2.0.0" @@ -1304,30 +1182,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.2.6" @@ -1581,7 +1441,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "io-lifetimes", "rustix", "windows-sys 0.42.0", @@ -1692,10 +1552,11 @@ dependencies = [ [[package]] name = "libproc" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6466fc1f834276563fbbd4be1c24236ef92bb9efdbd4691e07f1cf85a0b407f0" +checksum = "0b799ad155d75ce914c467ee5627b62247c20d4aedbd446f821484cebf3cded7" dependencies = [ + "bindgen", "errno", "libc", ] @@ -1914,18 +1775,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "nom" -version = "6.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" -dependencies = [ - "bitvec 0.19.6", - "funty 1.1.0", - "memchr", - "version_check", -] - [[package]] name = "nom" version = "7.1.0" @@ -2002,7 +1851,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -2039,6 +1888,7 @@ dependencies = [ "backoff", "base64", "bytes", + "clap", "cpp_demangle 0.3.5", "debugger", "dunce", @@ -2067,7 +1917,6 @@ dependencies = [ "sha2", "stacktrace-parser", "storage-queue", - "structopt", "strum", "strum_macros", "tempfile", @@ -2089,9 +1938,9 @@ dependencies = [ "anyhow", "async-trait", "backtrace", - "clap 3.2.4", + "clap", "downcast-rs", - "env_logger 0.9.0", + "env_logger", "futures", "log", "nix", @@ -2135,11 +1984,11 @@ dependencies = [ "azure_storage_blobs", "backoff", "chrono", - "clap 2.34.0", + "clap", "cobertura", "coverage", "crossterm 0.22.1", - "env_logger 0.9.0", + "env_logger", "flume", "futures", "hex", @@ -2514,12 +2363,11 @@ dependencies = [ [[package]] name = "proc-maps" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f62c16ccc63ce2f590b17b8b9b33616f59631b8982ad52ed21e7f6d936c409" +checksum = "2c790484f98e8b00e2385ebde989077698f99417307a74361001ada102f8c2ce" dependencies = [ "anyhow", - "bindgen", "libc", "libproc", "mach2", @@ -2588,12 +2436,6 @@ dependencies = [ "proc-macro2 1.0.47", ] -[[package]] -name = "radium" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" - [[package]] name = "radium" version = "0.7.0" @@ -3102,7 +2944,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "410b26ed97440d90ced3e2488c868d56a86e2064f5d7d6f417909b286afe25e5" dependencies = [ - "heck 0.4.0", + "heck", "proc-macro2 1.0.47", "quote 1.0.9", "syn 1.0.103", @@ -3132,14 +2974,14 @@ name = "srcview" version = "0.1.2" dependencies = [ "anyhow", - "env_logger 0.9.0", + "clap", + "env_logger", "log", "nom 7.1.0", "pdb", "quick-xml", "regex", "serde", - "structopt", ] [[package]] @@ -3207,42 +3049,12 @@ dependencies = [ "serde", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap 2.34.0", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2 1.0.47", - "quote 1.0.9", - "syn 1.0.103", -] - [[package]] name = "strum" version = "0.24.0" @@ -3255,7 +3067,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" dependencies = [ - "heck 0.4.0", + "heck", "proc-macro2 1.0.47", "quote 1.0.9", "rustversion", @@ -3298,7 +3110,7 @@ version = "10.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f94766a96b5834eaf72f9cb99a5a45e63fa44f1084705b705d9d31bb6455434" dependencies = [ - "bitvec 1.0.0", + "bitvec", "dmsort", "elementtree", "elsa", @@ -3415,21 +3227,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "thiserror" version = "1.0.37" @@ -3753,12 +3550,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.3" @@ -3905,15 +3696,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "which" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" -dependencies = [ - "libc", -] - [[package]] name = "win-util" version = "0.1.0" @@ -4119,12 +3901,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - [[package]] name = "wyz" version = "0.5.0" diff --git a/src/agent/dynamic-library/Cargo.toml b/src/agent/dynamic-library/Cargo.toml index 58eaedaeba..5734c6cdeb 100644 --- a/src/agent/dynamic-library/Cargo.toml +++ b/src/agent/dynamic-library/Cargo.toml @@ -6,9 +6,9 @@ license = "MIT" [dependencies] anyhow = "1.0" +clap = { version = "4.1.6", features = ["derive"] } lazy_static = "1.4" regex = "1.6" -structopt = "0.3" thiserror = "1.0" [target.'cfg(windows)'.dependencies] diff --git a/src/agent/dynamic-library/src/bin/dynamic-library.rs b/src/agent/dynamic-library/src/bin/dynamic-library.rs index b295d92171..97f0b3e7aa 100644 --- a/src/agent/dynamic-library/src/bin/dynamic-library.rs +++ b/src/agent/dynamic-library/src/bin/dynamic-library.rs @@ -4,22 +4,22 @@ use std::process::{Command, Stdio}; use anyhow::Result; -use structopt::StructOpt; +use clap::Parser; -#[derive(Debug, StructOpt)] +#[derive(Parser, Debug)] struct Opt { - #[structopt(min_values = 1)] + #[arg(required = true, num_args = 1..)] argv: Vec, - #[structopt(short, long)] + #[arg(short, long)] quiet: bool, - #[structopt(short, long)] + #[arg(short, long)] ld_library_path: Option, } fn main() -> Result<()> { - let opt = Opt::from_args(); + let opt = Opt::parse(); let exe = &opt.argv[0]; let mut cmd = Command::new(exe); diff --git a/src/agent/onefuzz-agent/Cargo.toml b/src/agent/onefuzz-agent/Cargo.toml index 8cf30a7da0..ffec30635d 100644 --- a/src/agent/onefuzz-agent/Cargo.toml +++ b/src/agent/onefuzz-agent/Cargo.toml @@ -10,7 +10,7 @@ license = "MIT" anyhow = { version = "1.0", features = ["backtrace"] } async-trait = "0.1" downcast-rs = "1.2" -env_logger = "0.9" +env_logger = "0.10" futures = "0.3" log = "0.4" onefuzz = { path = "../onefuzz" } @@ -25,7 +25,7 @@ storage-queue = { path = "../storage-queue" } tokio = { version = "1.24", features = ["full"] } url = { version = "2.3", features = ["serde"] } uuid = { version = "0.8", features = ["serde", "v4"] } -clap = { version = "3.2.4", features = ["derive", "cargo"] } +clap = { version = "4", features = ["derive", "cargo"] } reqwest-retry = { path = "../reqwest-retry" } onefuzz-telemetry = { path = "../onefuzz-telemetry" } backtrace = "0.3" diff --git a/src/agent/onefuzz-agent/src/main.rs b/src/agent/onefuzz-agent/src/main.rs index 457be81235..ce809bcf3b 100644 --- a/src/agent/onefuzz-agent/src/main.rs +++ b/src/agent/onefuzz-agent/src/main.rs @@ -54,20 +54,21 @@ enum Opt { #[derive(Parser, Debug)] struct RunOpt { - #[clap(short, long = "--config", parse(from_os_str))] + #[arg(short, long = "config")] config_path: Option, + /// re-executes as a child process, recording stdout/stderr to files in /// the specified directory - #[clap(short, long = "--redirect-output", parse(from_os_str))] + #[arg(short, long = "redirect-output")] redirect_output: Option, - #[clap(long = "--machine_id")] + #[arg(long = "machine_id")] machine_id: Option, - #[clap(long = "--machine_name")] + #[arg(long = "machine_name")] machine_name: Option, - #[clap(long = "--reset_lock", takes_value = false, action = ArgAction::SetTrue )] + #[arg(long = "reset_lock", action = ArgAction::SetTrue )] reset_node_lock: bool, } diff --git a/src/agent/onefuzz-task/Cargo.toml b/src/agent/onefuzz-task/Cargo.toml index 96d2ad7cf9..2c0c7c88f8 100644 --- a/src/agent/onefuzz-task/Cargo.toml +++ b/src/agent/onefuzz-task/Cargo.toml @@ -15,11 +15,11 @@ arraydeque = "0.5" async-trait = "0.1" atexit = { path = "../atexit" } backoff = { version = "0.4", features = ["tokio"] } -clap = "2.34" +clap = { version = "4", features = ["cargo", "string"] } cobertura = { path = "../cobertura" } coverage = { path = "../coverage" } crossterm = "0.22" -env_logger = "0.9" +env_logger = "0.10" flume = "0.10" futures = "0.3" hex = "0.4" diff --git a/src/agent/onefuzz-task/src/local/cmd.rs b/src/agent/onefuzz-task/src/local/cmd.rs index 937a792f3c..0f5d42ab92 100644 --- a/src/agent/onefuzz-task/src/local/cmd.rs +++ b/src/agent/onefuzz-task/src/local/cmd.rs @@ -9,7 +9,7 @@ use crate::local::{ libfuzzer_test_input, radamsa, test_input, tui::TerminalUi, }; use anyhow::{Context, Result}; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use std::str::FromStr; use std::time::Duration; use strum::IntoEnumIterator; @@ -37,17 +37,22 @@ enum Commands { const TIMEOUT: &str = "timeout"; const TUI: &str = "tui"; -pub async fn run(args: clap::ArgMatches<'static>) -> Result<()> { - let running_duration = value_t!(args, TIMEOUT, u64).ok(); - let start_ui = args.is_present(TUI); +pub async fn run(args: clap::ArgMatches) -> Result<()> { + let running_duration = args.get_one::(TIMEOUT).copied(); - let (cmd, sub_args) = args.subcommand(); - let command = - Commands::from_str(cmd).with_context(|| format!("unexpected subcommand: {cmd}"))?; + let start_ui = args.get_flag(TUI); - let sub_args = sub_args - .ok_or_else(|| anyhow!("missing subcommand arguments"))? - .to_owned(); + let (cmd, sub_args) = args.subcommand().ok_or_else(|| { + format_err!( + "Expected subcommand for 'local'. Use 'local help' to see available subcommands." + ) + })?; + + let command = Commands::from_str(cmd).with_context(|| { + format!("Unexpected subcommand: {cmd}. Use 'local help' to see available subcommands.") + })?; + + let sub_args = sub_args.clone(); let terminal = if start_ui { Some(TerminalUi::init()?) @@ -104,20 +109,20 @@ pub async fn run(args: clap::ArgMatches<'static>) -> Result<()> { } } -pub fn args(name: &str) -> App<'static, 'static> { - let mut cmd = SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + let mut cmd = Command::new(name) .about("pre-release local fuzzing") .arg( - Arg::with_name(TIMEOUT) + Arg::new(TIMEOUT) .long(TIMEOUT) - .help("The maximum running time in seconds") - .takes_value(true), + .value_parser(value_parser!(u64)) + .help("The maximum running time in seconds"), ) .arg( - Arg::with_name(TUI) + Arg::new(TUI) .long(TUI) .help("Enable the terminal UI") - .takes_value(false), + .action(ArgAction::SetTrue), ); for subcommand in Commands::iter() { diff --git a/src/agent/onefuzz-task/src/local/common.rs b/src/agent/onefuzz-task/src/local/common.rs index baf8fc73d5..73118d24ee 100644 --- a/src/agent/onefuzz-task/src/local/common.rs +++ b/src/agent/onefuzz-task/src/local/common.rs @@ -7,7 +7,7 @@ use std::{ use anyhow::Result; use backoff::{future::retry, Error as BackoffError, ExponentialBackoff}; -use clap::{App, Arg, ArgMatches}; +use clap::{Arg, ArgAction, ArgMatches, Command}; use flume::Sender; use onefuzz::{ blob::url::BlobContainerUrl, machine_id::MachineIdentity, monitor::DirectoryMonitor, @@ -76,40 +76,41 @@ pub struct LocalContext { pub event_sender: Option>, } -pub fn get_hash_map(args: &clap::ArgMatches<'_>, name: &str) -> Result> { +pub fn get_hash_map(args: &clap::ArgMatches, name: &str) -> Result> { let mut env = HashMap::new(); - for opt in args.values_of_lossy(name).unwrap_or_default() { + for opt in args.get_many::(name).unwrap_or_default() { let (k, v) = parse_key_value(opt)?; env.insert(k, v); } Ok(env) } -pub fn get_cmd_exe(cmd_type: CmdType, args: &clap::ArgMatches<'_>) -> Result { +pub fn get_cmd_exe(cmd_type: CmdType, args: &clap::ArgMatches) -> Result { let name = match cmd_type { CmdType::Target => TARGET_EXE, // CmdType::Supervisor => SUPERVISOR_EXE, CmdType::Generator => GENERATOR_EXE, }; - let exe = value_t!(args, name, String)?; - Ok(exe) + args.get_one::(name) + .cloned() + .ok_or_else(|| format_err!("missing argument {name}")) } -pub fn get_cmd_arg(cmd_type: CmdType, args: &clap::ArgMatches<'_>) -> Vec { +pub fn get_cmd_arg(cmd_type: CmdType, args: &clap::ArgMatches) -> Vec { let name = match cmd_type { CmdType::Target => TARGET_OPTIONS, // CmdType::Supervisor => SUPERVISOR_OPTIONS, CmdType::Generator => GENERATOR_OPTIONS, }; - args.values_of_lossy(name).unwrap_or_default() + args.get_many::(name) + .unwrap_or_default() + .cloned() + .collect() } -pub fn get_cmd_env( - cmd_type: CmdType, - args: &clap::ArgMatches<'_>, -) -> Result> { +pub fn get_cmd_env(cmd_type: CmdType, args: &clap::ArgMatches) -> Result> { let env_name = match cmd_type { CmdType::Target => TARGET_ENV, // CmdType::Supervisor => SUPERVISOR_ENV, @@ -118,58 +119,58 @@ pub fn get_cmd_env( get_hash_map(args, env_name) } -pub fn add_common_config(app: App<'static, 'static>) -> App<'static, 'static> { +pub fn add_common_config(app: Command) -> Command { app.arg( - Arg::with_name("job_id") + Arg::new("job_id") .long("job_id") - .takes_value(true) - .required(false), + .required(false) + .value_parser(value_parser!(uuid::Uuid)), ) .arg( - Arg::with_name("task_id") + Arg::new("task_id") .long("task_id") - .takes_value(true) - .required(false), + .required(false) + .value_parser(value_parser!(uuid::Uuid)), ) .arg( - Arg::with_name("instance_id") + Arg::new("instance_id") .long("instance_id") - .takes_value(true) - .required(false), + .required(false) + .value_parser(value_parser!(uuid::Uuid)), ) .arg( - Arg::with_name("setup_dir") + Arg::new("setup_dir") .long("setup_dir") - .takes_value(true) - .required(false), + .required(false) + .value_parser(value_parser!(PathBuf)), ) .arg( - Arg::with_name(CREATE_JOB_DIR) + Arg::new(CREATE_JOB_DIR) .long(CREATE_JOB_DIR) + .action(ArgAction::SetTrue) .required(false) .help("create a local job directory to sync the files"), ) } -fn get_uuid(name: &str, args: &ArgMatches<'_>) -> Result { - value_t!(args, name, String).map(|x| { - Uuid::parse_str(&x).map_err(|x| format_err!("invalid {}. uuid expected. {})", name, x)) - })? +fn get_uuid(name: &str, args: &ArgMatches) -> Result { + args.get_one::(name) + .copied() + .ok_or_else(|| format_err!("missing argument {name}")) } pub fn get_synced_dirs( name: &str, job_id: Uuid, task_id: Uuid, - args: &ArgMatches<'_>, + args: &ArgMatches, ) -> Result> { - let create_job_dir = args.is_present(CREATE_JOB_DIR); + let create_job_dir = args.get_flag(CREATE_JOB_DIR); let current_dir = std::env::current_dir()?; - args.values_of_os(name) + args.get_many::(name) .ok_or_else(|| anyhow!("argument '{}' not specified", name))? .enumerate() - .map(|(index, remote_path)| { - let path = PathBuf::from(remote_path); + .map(|(index, path)| { if create_job_dir { let remote_path = path.absolutize()?; let remote_url = Url::from_file_path(remote_path).expect("invalid file path"); @@ -182,7 +183,7 @@ pub fn get_synced_dirs( } else { Ok(SyncedDir { remote_path: None, - local_path: path, + local_path: path.clone(), }) } }) @@ -193,10 +194,14 @@ pub fn get_synced_dir( name: &str, job_id: Uuid, task_id: Uuid, - args: &ArgMatches<'_>, + args: &ArgMatches, ) -> Result { - let remote_path = value_t!(args, name, PathBuf)?.absolutize()?.into_owned(); - if args.is_present(CREATE_JOB_DIR) { + let remote_path = args + .get_one::(name) + .ok_or_else(|| format_err!("missing argument {name}"))? + .absolutize()? + .into_owned(); + if args.get_flag(CREATE_JOB_DIR) { let remote_url = Url::from_file_path(remote_path).map_err(|_| anyhow!("invalid file path"))?; let remote_blob_url = BlobContainerUrl::new(remote_url)?; @@ -218,11 +223,11 @@ pub fn get_synced_dir( // enables making the one-shot crash report generation, which isn't really a task, // consistent across multiple runs. pub async fn build_local_context( - args: &ArgMatches<'_>, + args: &ArgMatches, generate_task_id: bool, event_sender: Option>, ) -> Result { - let job_id = get_uuid("job_id", args).unwrap_or_else(|_| Uuid::nil()); + let job_id = get_uuid("job_id", args).unwrap_or_default(); let task_id = get_uuid("task_id", args).unwrap_or_else(|_| { if generate_task_id { Uuid::new_v4() @@ -230,12 +235,12 @@ pub async fn build_local_context( Uuid::nil() } }); - let instance_id = get_uuid("instance_id", args).unwrap_or_else(|_| Uuid::nil()); + let instance_id = get_uuid("instance_id", args).unwrap_or_default(); - let setup_dir = if args.is_present(SETUP_DIR) { - value_t!(args, SETUP_DIR, PathBuf)? - } else if args.is_present(TARGET_EXE) { - value_t!(args, TARGET_EXE, PathBuf)? + let setup_dir = if let Some(setup_dir) = args.get_one::(SETUP_DIR) { + setup_dir.clone() + } else if let Some(target_exe) = args.get_one::(TARGET_EXE) { + PathBuf::from(target_exe) .parent() .map(|x| x.to_path_buf()) .unwrap_or_default() diff --git a/src/agent/onefuzz-task/src/local/coverage.rs b/src/agent/onefuzz-task/src/local/coverage.rs index 69d38a595c..a5d53a09f0 100644 --- a/src/agent/onefuzz-task/src/local/coverage.rs +++ b/src/agent/onefuzz-task/src/local/coverage.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, @@ -13,14 +15,14 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; use storage_queue::QueueClient; use super::common::{SyncCountDirMonitor, UiEvent}; pub fn build_coverage_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, local_job: bool, input_queue: Option, common: CommonConfig, @@ -29,7 +31,7 @@ pub fn build_coverage_config( let target_exe = get_cmd_exe(CmdType::Target, args)?.into(); let target_env = get_cmd_env(CmdType::Target, args)?; let mut target_options = get_cmd_arg(CmdType::Target, args); - let target_timeout = value_t!(args, TARGET_TIMEOUT, u64).ok(); + let target_timeout = args.get_one::(TARGET_TIMEOUT).copied(); let readonly_inputs = if local_job { vec![ @@ -67,7 +69,7 @@ pub fn build_coverage_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_coverage_config( args, @@ -81,54 +83,47 @@ pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option Vec> { +pub fn build_shared_args(local_job: bool) -> Vec { let mut args = vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .long(TARGET_OPTIONS) .default_value("{input}") - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) + Arg::new(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)) .long(TARGET_TIMEOUT), - Arg::with_name(COVERAGE_DIR) - .takes_value(true) + Arg::new(COVERAGE_DIR) .required(!local_job) + .value_parser(value_parser!(PathBuf)) .long(COVERAGE_DIR), - Arg::with_name(CHECK_FUZZER_HELP) - .takes_value(false) + Arg::new(CHECK_FUZZER_HELP) + .action(ArgAction::SetTrue) .long(CHECK_FUZZER_HELP), ]; if local_job { args.push( - Arg::with_name(INPUTS_DIR) + Arg::new(INPUTS_DIR) .long(INPUTS_DIR) - .takes_value(true) - .required(true), + .required(true) + .value_parser(value_parser!(PathBuf)), ) } else { args.push( - Arg::with_name(READONLY_INPUTS) - .takes_value(true) + Arg::new(READONLY_INPUTS) .required(true) .long(READONLY_INPUTS) - .multiple(true), + .value_parser(value_parser!(PathBuf)) + .num_args(1..), ) } args } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only coverage task") .args(&build_shared_args(false)) } diff --git a/src/agent/onefuzz-task/src/local/generic_analysis.rs b/src/agent/onefuzz-task/src/local/generic_analysis.rs index 4fdc7e0041..756446d140 100644 --- a/src/agent/onefuzz-task/src/local/generic_analysis.rs +++ b/src/agent/onefuzz-task/src/local/generic_analysis.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_exe, get_hash_map, get_synced_dir, CmdType, @@ -14,12 +16,12 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, Command}; use flume::Sender; use storage_queue::QueueClient; pub fn build_analysis_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, input_queue: Option, common: CommonConfig, event_sender: Option>, @@ -27,8 +29,17 @@ pub fn build_analysis_config( let target_exe = get_cmd_exe(CmdType::Target, args)?.into(); let target_options = get_cmd_arg(CmdType::Target, args); - let analyzer_exe = value_t!(args, ANALYZER_EXE, String)?; - let analyzer_options = args.values_of_lossy(ANALYZER_OPTIONS).unwrap_or_default(); + let analyzer_exe = args + .get_one::(ANALYZER_EXE) + .cloned() + .ok_or_else(|| format_err!("expected {ANALYZER_EXE}"))?; + + let analyzer_options = args + .get_many::(ANALYZER_OPTIONS) + .unwrap_or_default() + .map(|x| x.to_string()) + .collect(); + let analyzer_env = get_hash_map(args, ANALYZER_ENV)?; let analysis = get_synced_dir(ANALYSIS_DIR, common.job_id, common.task_id, args)? .monitor_count(&event_sender)?; @@ -69,61 +80,54 @@ pub fn build_analysis_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_analysis_config(args, None, context.common_config.clone(), event_sender)?; run_analysis(config).await } -pub fn build_shared_args(required_task: bool) -> Vec> { +pub fn build_shared_args(required_task: bool) -> Vec { vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV) .long(TARGET_ENV) .requires(TARGET_EXE) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + .num_args(0..), + Arg::new(TARGET_OPTIONS) .long(TARGET_OPTIONS) - .takes_value(true) .default_value("{input}") - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(CRASHES_DIR) + Arg::new(CRASHES_DIR) .long(CRASHES_DIR) - .takes_value(true), - Arg::with_name(ANALYZER_OPTIONS) + .value_parser(value_parser!(PathBuf)), + Arg::new(ANALYZER_OPTIONS) .long(ANALYZER_OPTIONS) .requires(ANALYZER_EXE) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(ANALYZER_ENV) + Arg::new(ANALYZER_ENV) .long(ANALYZER_ENV) .requires(ANALYZER_EXE) - .takes_value(true) - .multiple(true), - Arg::with_name(TOOLS_DIR).long(TOOLS_DIR).takes_value(true), - Arg::with_name(ANALYZER_EXE) + .num_args(0..), + Arg::new(TOOLS_DIR) + .long(TOOLS_DIR) + .value_parser(value_parser!(PathBuf)), + Arg::new(ANALYZER_EXE) .long(ANALYZER_EXE) - .takes_value(true) .requires(ANALYSIS_DIR) .requires(CRASHES_DIR) .required(required_task), - Arg::with_name(ANALYSIS_DIR) + Arg::new(ANALYSIS_DIR) .long(ANALYSIS_DIR) - .takes_value(true) .requires(ANALYZER_EXE) .requires(CRASHES_DIR) .required(required_task), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only generic analysis") .args(&build_shared_args(true)) } diff --git a/src/agent/onefuzz-task/src/local/generic_crash_report.rs b/src/agent/onefuzz-task/src/local/generic_crash_report.rs index 1feb49acb9..aebd45aa08 100644 --- a/src/agent/onefuzz-task/src/local/generic_crash_report.rs +++ b/src/agent/onefuzz-task/src/local/generic_crash_report.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, CmdType, @@ -14,12 +16,12 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; use storage_queue::QueueClient; pub fn build_report_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, input_queue: Option, common: CommonConfig, event_sender: Option>, @@ -50,12 +52,16 @@ pub fn build_report_config( )?) .monitor_count(&event_sender)?; - let target_timeout = value_t!(args, TARGET_TIMEOUT, u64).ok(); + let target_timeout = args.get_one::(TARGET_TIMEOUT).copied(); + + let check_retry_count = args + .get_one::(CHECK_RETRY_COUNT) + .copied() + .expect("has a default"); - let check_retry_count = value_t!(args, CHECK_RETRY_COUNT, u64)?; - let check_queue = !args.is_present(DISABLE_CHECK_QUEUE); - let check_asan_log = args.is_present(CHECK_ASAN_LOG); - let check_debugger = !args.is_present(DISABLE_CHECK_DEBUGGER); + let check_queue = !args.get_flag(DISABLE_CHECK_QUEUE); + let check_asan_log = args.get_flag(CHECK_ASAN_LOG); + let check_debugger = !args.get_flag(DISABLE_CHECK_DEBUGGER); let config = Config { target_exe, @@ -78,66 +84,59 @@ pub fn build_report_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_report_config(args, None, context.common_config.clone(), event_sender)?; ReportTask::new(config).managed_run().await } -pub fn build_shared_args() -> Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .default_value("{input}") .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(CRASHES_DIR) + Arg::new(CRASHES_DIR) .long(CRASHES_DIR) - .takes_value(true) - .required(true), - Arg::with_name(REPORTS_DIR) + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(REPORTS_DIR) .long(REPORTS_DIR) - .takes_value(true) - .required(false), - Arg::with_name(NO_REPRO_DIR) + .required(false) + .value_parser(value_parser!(PathBuf)), + Arg::new(NO_REPRO_DIR) .long(NO_REPRO_DIR) - .takes_value(true) - .required(false), - Arg::with_name(UNIQUE_REPORTS_DIR) + .required(false) + .value_parser(value_parser!(PathBuf)), + Arg::new(UNIQUE_REPORTS_DIR) .long(UNIQUE_REPORTS_DIR) - .takes_value(true) + .value_parser(value_parser!(PathBuf)) .required(true), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) + Arg::new(TARGET_TIMEOUT) .long(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)) .default_value("30"), - Arg::with_name(CHECK_RETRY_COUNT) - .takes_value(true) + Arg::new(CHECK_RETRY_COUNT) .long(CHECK_RETRY_COUNT) + .value_parser(value_parser!(u64)) .default_value("0"), - Arg::with_name(DISABLE_CHECK_QUEUE) - .takes_value(false) + Arg::new(DISABLE_CHECK_QUEUE) + .action(ArgAction::SetTrue) .long(DISABLE_CHECK_QUEUE), - Arg::with_name(CHECK_ASAN_LOG) - .takes_value(false) + Arg::new(CHECK_ASAN_LOG) + .action(ArgAction::SetTrue) .long(CHECK_ASAN_LOG), - Arg::with_name(DISABLE_CHECK_DEBUGGER) - .takes_value(false) + Arg::new(DISABLE_CHECK_DEBUGGER) + .action(ArgAction::SetTrue) .long(DISABLE_CHECK_DEBUGGER), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only generic crash report") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/local/generic_generator.rs b/src/agent/onefuzz-task/src/local/generic_generator.rs index 9b998f5e88..a6b0777348 100644 --- a/src/agent/onefuzz-task/src/local/generic_generator.rs +++ b/src/agent/onefuzz-task/src/local/generic_generator.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, @@ -15,11 +17,11 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; pub fn build_fuzz_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, common: CommonConfig, event_sender: Option>, ) -> Result { @@ -37,11 +39,20 @@ pub fn build_fuzz_config( .map(|sd| sd.monitor_count(&event_sender)) .collect::>>()?; - let rename_output = args.is_present(RENAME_OUTPUT); - let check_asan_log = args.is_present(CHECK_ASAN_LOG); - let check_debugger = !args.is_present(DISABLE_CHECK_DEBUGGER); - let check_retry_count = value_t!(args, CHECK_RETRY_COUNT, u64)?; - let target_timeout = Some(value_t!(args, TARGET_TIMEOUT, u64)?); + let rename_output = args.get_flag(RENAME_OUTPUT); + let check_asan_log = args.get_flag(CHECK_ASAN_LOG); + let check_debugger = !args.get_flag(DISABLE_CHECK_DEBUGGER); + + let check_retry_count = args + .get_one::(CHECK_RETRY_COUNT) + .copied() + .expect("has a default"); + + let target_timeout = Some( + args.get_one::(TARGET_TIMEOUT) + .copied() + .expect("has a default"), + ); let tools = get_synced_dir(TOOLS_DIR, common.job_id, common.task_id, args) .ok() @@ -71,75 +82,65 @@ pub fn build_fuzz_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_fuzz_config(args, context.common_config.clone(), event_sender)?; GeneratorTask::new(config).run().await } -pub fn build_shared_args() -> Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .default_value("{input}") .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(GENERATOR_EXE) + Arg::new(GENERATOR_EXE) .long(GENERATOR_EXE) .default_value("radamsa") - .takes_value(true) .required(true), - Arg::with_name(GENERATOR_ENV) - .long(GENERATOR_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(GENERATOR_OPTIONS) + Arg::new(GENERATOR_ENV).long(GENERATOR_ENV).num_args(0..), + Arg::new(GENERATOR_OPTIONS) .long(GENERATOR_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .default_value("-H sha256 -o {generated_inputs}/input-%h.%s -n 100 -r {input_corpus}") .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(CRASHES_DIR) - .takes_value(true) + Arg::new(CRASHES_DIR) .required(true) - .long(CRASHES_DIR), - Arg::with_name(READONLY_INPUTS) - .takes_value(true) + .long(CRASHES_DIR) + .value_parser(value_parser!(PathBuf)), + Arg::new(READONLY_INPUTS) .required(true) - .multiple(true) + .num_args(1..) + .value_parser(value_parser!(PathBuf)) .long(READONLY_INPUTS), - Arg::with_name(TOOLS_DIR).takes_value(true).long(TOOLS_DIR), - Arg::with_name(CHECK_RETRY_COUNT) - .takes_value(true) + Arg::new(TOOLS_DIR) + .long(TOOLS_DIR) + .value_parser(value_parser!(PathBuf)), + Arg::new(CHECK_RETRY_COUNT) .long(CHECK_RETRY_COUNT) + .value_parser(value_parser!(u64)) .default_value("0"), - Arg::with_name(CHECK_ASAN_LOG) - .takes_value(false) + Arg::new(CHECK_ASAN_LOG) + .action(ArgAction::SetTrue) .long(CHECK_ASAN_LOG), - Arg::with_name(RENAME_OUTPUT) - .takes_value(false) + Arg::new(RENAME_OUTPUT) + .action(ArgAction::SetTrue) .long(RENAME_OUTPUT), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) + Arg::new(TARGET_TIMEOUT) .long(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)) .default_value("30"), - Arg::with_name(DISABLE_CHECK_DEBUGGER) - .takes_value(false) + Arg::new(DISABLE_CHECK_DEBUGGER) + .action(ArgAction::SetTrue) .long(DISABLE_CHECK_DEBUGGER), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only generator fuzzing task") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/local/libfuzzer.rs b/src/agent/onefuzz-task/src/local/libfuzzer.rs index 3cc95ce701..f3dc1778e0 100644 --- a/src/agent/onefuzz-task/src/local/libfuzzer.rs +++ b/src/agent/onefuzz-task/src/local/libfuzzer.rs @@ -26,14 +26,14 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, SubCommand}; +use clap::Command; use flume::Sender; use onefuzz::utils::try_wait_all_join_handles; use std::collections::HashSet; use tokio::task::spawn; use uuid::Uuid; -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let fuzz_config = build_fuzz_config(args, context.common_config.clone(), event_sender.clone())?; let crash_dir = fuzz_config @@ -51,7 +51,7 @@ pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option, event_sender: Option, event_sender: Option, event_sender: Option, event_sender: Option App<'static, 'static> { - let mut app = SubCommand::with_name(name).about("run a local libfuzzer & crash reporting task"); +pub fn args(name: &'static str) -> Command { + let mut app = Command::new(name).about("run a local libfuzzer & crash reporting task"); let mut used = HashSet::new(); - for args in [ + for args in &[ build_fuzz_args(), build_crash_args(), build_analysis_args(false), @@ -144,11 +144,9 @@ pub fn args(name: &'static str) -> App<'static, 'static> { build_regression_args(false), ] { for arg in args { - if used.contains(arg.b.name) { - continue; + if used.insert(arg.get_id()) { + app = app.arg(arg); } - used.insert(arg.b.name.to_string()); - app = app.arg(arg); } } diff --git a/src/agent/onefuzz-task/src/local/libfuzzer_crash_report.rs b/src/agent/onefuzz-task/src/local/libfuzzer_crash_report.rs index 3a6e2cd7b6..be6ac1cefd 100644 --- a/src/agent/onefuzz-task/src/local/libfuzzer_crash_report.rs +++ b/src/agent/onefuzz-task/src/local/libfuzzer_crash_report.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, CmdType, @@ -14,12 +16,12 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; use storage_queue::QueueClient; pub fn build_report_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, input_queue: Option, common: CommonConfig, event_sender: Option>, @@ -43,13 +45,16 @@ pub fn build_report_config( .ok() .monitor_count(&event_sender)?; - let target_timeout = value_t!(args, TARGET_TIMEOUT, u64).ok(); + let target_timeout = args.get_one::(TARGET_TIMEOUT).copied(); - let check_retry_count = value_t!(args, CHECK_RETRY_COUNT, u64)?; + let check_retry_count = args + .get_one::(CHECK_RETRY_COUNT) + .copied() + .expect("has a default"); - let check_queue = !args.is_present(DISABLE_CHECK_QUEUE); + let check_queue = !args.get_flag(DISABLE_CHECK_QUEUE); - let check_fuzzer_help = args.is_present(CHECK_FUZZER_HELP); + let check_fuzzer_help = args.get_flag(CHECK_FUZZER_HELP); let crashes = if input_queue.is_none() { crashes } else { None }; @@ -73,61 +78,54 @@ pub fn build_report_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_report_config(args, None, context.common_config.clone(), event_sender)?; ReportTask::new(config).managed_run().await } -pub fn build_shared_args() -> Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(CRASHES_DIR) + Arg::new(CRASHES_DIR) .long(CRASHES_DIR) - .takes_value(true) - .required(true), - Arg::with_name(REPORTS_DIR) + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(REPORTS_DIR) .long(REPORTS_DIR) - .takes_value(true) - .required(false), - Arg::with_name(NO_REPRO_DIR) + .required(false) + .value_parser(value_parser!(PathBuf)), + Arg::new(NO_REPRO_DIR) .long(NO_REPRO_DIR) - .takes_value(true) - .required(false), - Arg::with_name(UNIQUE_REPORTS_DIR) + .required(false) + .value_parser(value_parser!(PathBuf)), + Arg::new(UNIQUE_REPORTS_DIR) .long(UNIQUE_REPORTS_DIR) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)) .long(TARGET_TIMEOUT), - Arg::with_name(CHECK_RETRY_COUNT) - .takes_value(true) + Arg::new(CHECK_RETRY_COUNT) .long(CHECK_RETRY_COUNT) + .value_parser(value_parser!(u64)) .default_value("0"), - Arg::with_name(DISABLE_CHECK_QUEUE) - .takes_value(false) + Arg::new(DISABLE_CHECK_QUEUE) + .action(ArgAction::SetTrue) .long(DISABLE_CHECK_QUEUE), - Arg::with_name(CHECK_FUZZER_HELP) - .takes_value(false) + Arg::new(CHECK_FUZZER_HELP) + .action(ArgAction::SetTrue) .long(CHECK_FUZZER_HELP), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only libfuzzer crash report task") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/local/libfuzzer_fuzz.rs b/src/agent/onefuzz-task/src/local/libfuzzer_fuzz.rs index f0a5b709f3..74cb451189 100644 --- a/src/agent/onefuzz-task/src/local/libfuzzer_fuzz.rs +++ b/src/agent/onefuzz-task/src/local/libfuzzer_fuzz.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, CmdType, @@ -13,13 +15,13 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; const EXPECT_CRASH_ON_FAILURE: &str = "expect_crash_on_failure"; pub fn build_fuzz_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, common: CommonConfig, event_sender: Option>, ) -> Result { @@ -32,10 +34,14 @@ pub fn build_fuzz_config( let target_env = get_cmd_env(CmdType::Target, args)?; let target_options = get_cmd_arg(CmdType::Target, args); - let target_workers = value_t!(args, "target_workers", usize).unwrap_or_default(); + let target_workers = args + .get_one::("target_workers") + .copied() + .unwrap_or_default(); + let readonly_inputs = None; - let check_fuzzer_help = args.is_present(CHECK_FUZZER_HELP); - let expect_crash_on_failure = args.is_present(EXPECT_CRASH_ON_FAILURE); + let check_fuzzer_help = args.get_flag(CHECK_FUZZER_HELP); + let expect_crash_on_failure = args.get_flag(EXPECT_CRASH_ON_FAILURE); let ensemble_sync_delay = None; @@ -57,49 +63,42 @@ pub fn build_fuzz_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_fuzz_config(args, context.common_config.clone(), event_sender)?; LibFuzzerFuzzTask::new(config)?.run().await } -pub fn build_shared_args() -> Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(INPUTS_DIR) + Arg::new(INPUTS_DIR) .long(INPUTS_DIR) - .takes_value(true) - .required(true), - Arg::with_name(CRASHES_DIR) + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(CRASHES_DIR) .long(CRASHES_DIR) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_WORKERS) + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(TARGET_WORKERS) .long(TARGET_WORKERS) - .takes_value(true), - Arg::with_name(CHECK_FUZZER_HELP) - .takes_value(false) + .value_parser(value_parser!(u64)), + Arg::new(CHECK_FUZZER_HELP) + .action(ArgAction::SetTrue) .long(CHECK_FUZZER_HELP), - Arg::with_name(EXPECT_CRASH_ON_FAILURE) - .takes_value(false) + Arg::new(EXPECT_CRASH_ON_FAILURE) + .action(ArgAction::SetTrue) .long(EXPECT_CRASH_ON_FAILURE), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only libfuzzer fuzzing task") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/local/libfuzzer_merge.rs b/src/agent/onefuzz-task/src/local/libfuzzer_merge.rs index 2f650efa02..6d7aed7b2a 100644 --- a/src/agent/onefuzz-task/src/local/libfuzzer_merge.rs +++ b/src/agent/onefuzz-task/src/local/libfuzzer_merge.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, @@ -14,12 +16,12 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; use storage_queue::QueueClient; pub fn build_merge_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, input_queue: Option, common: CommonConfig, event_sender: Option>, @@ -27,7 +29,7 @@ pub fn build_merge_config( let target_exe = get_cmd_exe(CmdType::Target, args)?.into(); let target_env = get_cmd_env(CmdType::Target, args)?; let target_options = get_cmd_arg(CmdType::Target, args); - let check_fuzzer_help = args.is_present(CHECK_FUZZER_HELP); + let check_fuzzer_help = args.get_flag(CHECK_FUZZER_HELP); let inputs = get_synced_dirs(ANALYSIS_INPUTS, common.job_id, common.task_id, args)? .into_iter() .map(|sd| sd.monitor_count(&event_sender)) @@ -35,7 +37,10 @@ pub fn build_merge_config( let unique_inputs = get_synced_dir(ANALYSIS_UNIQUE_INPUTS, common.job_id, common.task_id, args)? .monitor_count(&event_sender)?; - let preserve_existing_outputs = value_t!(args, PRESERVE_EXISTING_OUTPUTS, bool)?; + let preserve_existing_outputs = args + .get_one::(PRESERVE_EXISTING_OUTPUTS) + .copied() + .unwrap_or_default(); let config = Config { target_exe, @@ -52,39 +57,32 @@ pub fn build_merge_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_merge_config(args, None, context.common_config.clone(), event_sender)?; spawn(std::sync::Arc::new(config)).await } -pub fn build_shared_args() -> Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(CHECK_FUZZER_HELP) - .takes_value(false) + Arg::new(CHECK_FUZZER_HELP) + .action(ArgAction::SetTrue) .long(CHECK_FUZZER_HELP), - Arg::with_name(INPUTS_DIR) + Arg::new(INPUTS_DIR) .long(INPUTS_DIR) - .takes_value(true) - .multiple(true), + .value_parser(value_parser!(PathBuf)) + .num_args(0..), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only libfuzzer crash report task") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/local/libfuzzer_regression.rs b/src/agent/onefuzz-task/src/local/libfuzzer_regression.rs index 9624900a67..da5af6d1b1 100644 --- a/src/agent/onefuzz-task/src/local/libfuzzer_regression.rs +++ b/src/agent/onefuzz-task/src/local/libfuzzer_regression.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::path::PathBuf; + use crate::{ local::common::{ build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, CmdType, @@ -14,26 +16,29 @@ use crate::{ }, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; const REPORT_NAMES: &str = "report_names"; pub fn build_regression_config( - args: &clap::ArgMatches<'_>, + args: &clap::ArgMatches, common: CommonConfig, event_sender: Option>, ) -> Result { let target_exe = get_cmd_exe(CmdType::Target, args)?.into(); let target_env = get_cmd_env(CmdType::Target, args)?; let target_options = get_cmd_arg(CmdType::Target, args); - let target_timeout = value_t!(args, TARGET_TIMEOUT, u64).ok(); + let target_timeout = args.get_one::(TARGET_TIMEOUT).copied(); let crashes = get_synced_dir(CRASHES_DIR, common.job_id, common.task_id, args)? .monitor_count(&event_sender)?; let regression_reports = get_synced_dir(REGRESSION_REPORTS_DIR, common.job_id, common.task_id, args)? .monitor_count(&event_sender)?; - let check_retry_count = value_t!(args, CHECK_RETRY_COUNT, u64)?; + let check_retry_count = args + .get_one::(CHECK_RETRY_COUNT) + .copied() + .expect("has a default value"); let reports = get_synced_dir(REPORTS_DIR, common.job_id, common.task_id, args) .ok() @@ -45,13 +50,11 @@ pub fn build_regression_config( .ok() .monitor_count(&event_sender)?; - let report_list = if args.is_present(REPORT_NAMES) { - Some(values_t!(args, REPORT_NAMES, String)?) - } else { - None - }; + let report_list: Option> = args + .get_many::(REPORT_NAMES) + .map(|x| x.cloned().collect()); - let check_fuzzer_help = args.is_present(CHECK_FUZZER_HELP); + let check_fuzzer_help = args.get_flag(CHECK_FUZZER_HELP); let config = Config { target_exe, @@ -73,75 +76,63 @@ pub fn build_regression_config( Ok(config) } -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let config = build_regression_config(args, context.common_config.clone(), event_sender)?; LibFuzzerRegressionTask::new(config).run().await } -pub fn build_shared_args(local_job: bool) -> Vec> { +pub fn build_shared_args(local_job: bool) -> Vec { let mut args = vec![ - Arg::with_name(TARGET_EXE) - .long(TARGET_EXE) - .takes_value(true) - .required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).long(TARGET_EXE).required(true), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(COVERAGE_DIR) - .takes_value(true) + Arg::new(COVERAGE_DIR) .required(!local_job) - .long(COVERAGE_DIR), - Arg::with_name(CHECK_FUZZER_HELP) - .takes_value(false) + .long(COVERAGE_DIR) + .value_parser(value_parser!(PathBuf)), + Arg::new(CHECK_FUZZER_HELP) + .action(ArgAction::SetTrue) .long(CHECK_FUZZER_HELP), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) - .long(TARGET_TIMEOUT), - Arg::with_name(CRASHES_DIR) + Arg::new(TARGET_TIMEOUT) + .long(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)), + Arg::new(CRASHES_DIR) .long(CRASHES_DIR) - .takes_value(true) - .required(true), - Arg::with_name(REGRESSION_REPORTS_DIR) + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(REGRESSION_REPORTS_DIR) .long(REGRESSION_REPORTS_DIR) - .takes_value(true) - .required(local_job), - Arg::with_name(REPORTS_DIR) + .required(local_job) + .value_parser(value_parser!(PathBuf)), + Arg::new(REPORTS_DIR) .long(REPORTS_DIR) - .takes_value(true) - .required(false), - Arg::with_name(NO_REPRO_DIR) + .required(false) + .value_parser(value_parser!(PathBuf)), + Arg::new(NO_REPRO_DIR) .long(NO_REPRO_DIR) - .takes_value(true) - .required(false), - Arg::with_name(UNIQUE_REPORTS_DIR) + .required(false) + .value_parser(value_parser!(PathBuf)), + Arg::new(UNIQUE_REPORTS_DIR) .long(UNIQUE_REPORTS_DIR) - .takes_value(true) + .value_parser(value_parser!(PathBuf)) .required(true), - Arg::with_name(CHECK_RETRY_COUNT) - .takes_value(true) + Arg::new(CHECK_RETRY_COUNT) .long(CHECK_RETRY_COUNT) + .value_parser(value_parser!(u64)) .default_value("0"), ]; if local_job { - args.push( - Arg::with_name(REPORT_NAMES) - .long(REPORT_NAMES) - .takes_value(true) - .multiple(true), - ) + args.push(Arg::new(REPORT_NAMES).long(REPORT_NAMES).num_args(0..)) } args } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("execute a local-only libfuzzer regression task") - .args(&build_shared_args(false)) + .args(&build_shared_args(true)) } diff --git a/src/agent/onefuzz-task/src/local/libfuzzer_test_input.rs b/src/agent/onefuzz-task/src/local/libfuzzer_test_input.rs index 4fa03f8be4..af5468d4e6 100644 --- a/src/agent/onefuzz-task/src/local/libfuzzer_test_input.rs +++ b/src/agent/onefuzz-task/src/local/libfuzzer_test_input.rs @@ -9,19 +9,26 @@ use crate::{ tasks::report::libfuzzer_report::{test_input, TestInputArgs}, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, Command}; use flume::Sender; use std::path::PathBuf; -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender).await?; - let target_exe = value_t!(args, TARGET_EXE, PathBuf)?; + let target_exe = args + .get_one::(TARGET_EXE) + .expect("marked as required"); let target_env = get_cmd_env(CmdType::Target, args)?; let target_options = get_cmd_arg(CmdType::Target, args); - let input = value_t!(args, "input", PathBuf)?; - let target_timeout = value_t!(args, TARGET_TIMEOUT, u64).ok(); - let check_retry_count = value_t!(args, CHECK_RETRY_COUNT, u64)?; + let input = args + .get_one::("input") + .expect("marked as required"); + let target_timeout = args.get_one::(TARGET_TIMEOUT).copied(); + let check_retry_count = args + .get_one::(CHECK_RETRY_COUNT) + .copied() + .expect("has a default value"); let config = TestInputArgs { target_exe: target_exe.as_path(), @@ -43,32 +50,30 @@ pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE).takes_value(true).required(true), - Arg::with_name("input").takes_value(true).required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).required(true), + Arg::new("input") + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .default_value("{input}") .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) - .long(TARGET_TIMEOUT), - Arg::with_name(CHECK_RETRY_COUNT) - .takes_value(true) + Arg::new(TARGET_TIMEOUT) + .long(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)), + Arg::new(CHECK_RETRY_COUNT) .long(CHECK_RETRY_COUNT) + .value_parser(value_parser!(u64)) .default_value("0"), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("test a libfuzzer application with a specific input") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/local/radamsa.rs b/src/agent/onefuzz-task/src/local/radamsa.rs index 14906740d3..4d84de027a 100644 --- a/src/agent/onefuzz-task/src/local/radamsa.rs +++ b/src/agent/onefuzz-task/src/local/radamsa.rs @@ -10,14 +10,14 @@ use crate::{ tasks::{config::CommonConfig, fuzz::generator::GeneratorTask, report::generic::ReportTask}, }; use anyhow::{Context, Result}; -use clap::{App, SubCommand}; +use clap::Command; use flume::Sender; use onefuzz::utils::try_wait_all_join_handles; use std::collections::HashSet; use tokio::task::spawn; use uuid::Uuid; -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, true, event_sender.clone()).await?; let fuzz_config = build_fuzz_config(args, context.common_config.clone(), event_sender.clone())?; let crash_dir = fuzz_config @@ -62,17 +62,15 @@ pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option App<'static, 'static> { - let mut app = SubCommand::with_name(name).about("run a local generator & crash reporting job"); +pub fn args(name: &'static str) -> Command { + let mut app = Command::new(name).about("run a local generator & crash reporting job"); let mut used = HashSet::new(); - for args in [build_fuzz_args(), build_crash_args()] { + for args in &[build_fuzz_args(), build_crash_args()] { for arg in args { - if used.contains(arg.b.name) { - continue; + if used.insert(arg.get_id()) { + app = app.arg(arg); } - used.insert(arg.b.name.to_string()); - app = app.arg(arg); } } diff --git a/src/agent/onefuzz-task/src/local/test_input.rs b/src/agent/onefuzz-task/src/local/test_input.rs index 4a775624bd..42076b3f27 100644 --- a/src/agent/onefuzz-task/src/local/test_input.rs +++ b/src/agent/onefuzz-task/src/local/test_input.rs @@ -10,21 +10,28 @@ use crate::{ tasks::report::generic::{test_input, TestInputArgs}, }; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, ArgAction, Command}; use flume::Sender; use std::path::PathBuf; -pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches, event_sender: Option>) -> Result<()> { let context = build_local_context(args, false, event_sender).await?; - let target_exe = value_t!(args, TARGET_EXE, PathBuf)?; + let target_exe = args + .get_one::(TARGET_EXE) + .expect("is marked required"); let target_env = get_cmd_env(CmdType::Target, args)?; let target_options = get_cmd_arg(CmdType::Target, args); - let input = value_t!(args, "input", PathBuf)?; - let target_timeout = value_t!(args, TARGET_TIMEOUT, u64).ok(); - let check_retry_count = value_t!(args, CHECK_RETRY_COUNT, u64)?; - let check_asan_log = args.is_present(CHECK_ASAN_LOG); - let check_debugger = !args.is_present(DISABLE_CHECK_DEBUGGER); + let input = args + .get_one::("input") + .expect("is marked required"); + let target_timeout = args.get_one::(TARGET_TIMEOUT).copied(); + let check_retry_count = args + .get_one::(CHECK_RETRY_COUNT) + .copied() + .expect("has default value"); + let check_asan_log = args.get_flag(CHECK_ASAN_LOG); + let check_debugger = !args.get_flag(DISABLE_CHECK_DEBUGGER); let config = TestInputArgs { target_exe: target_exe.as_path(), @@ -48,38 +55,36 @@ pub async fn run(args: &clap::ArgMatches<'_>, event_sender: Option Vec> { +pub fn build_shared_args() -> Vec { vec![ - Arg::with_name(TARGET_EXE).takes_value(true).required(true), - Arg::with_name("input").takes_value(true).required(true), - Arg::with_name(TARGET_ENV) - .long(TARGET_ENV) - .takes_value(true) - .multiple(true), - Arg::with_name(TARGET_OPTIONS) + Arg::new(TARGET_EXE).required(true), + Arg::new("input") + .required(true) + .value_parser(value_parser!(PathBuf)), + Arg::new(TARGET_ENV).long(TARGET_ENV).num_args(0..), + Arg::new(TARGET_OPTIONS) .default_value("{input}") .long(TARGET_OPTIONS) - .takes_value(true) - .value_delimiter(" ") + .value_delimiter(' ') .help("Use a quoted string with space separation to denote multiple arguments"), - Arg::with_name(TARGET_TIMEOUT) - .takes_value(true) - .long(TARGET_TIMEOUT), - Arg::with_name(CHECK_RETRY_COUNT) - .takes_value(true) + Arg::new(TARGET_TIMEOUT) + .long(TARGET_TIMEOUT) + .value_parser(value_parser!(u64)), + Arg::new(CHECK_RETRY_COUNT) .long(CHECK_RETRY_COUNT) + .value_parser(value_parser!(u64)) .default_value("0"), - Arg::with_name(CHECK_ASAN_LOG) - .takes_value(false) + Arg::new(CHECK_ASAN_LOG) + .action(ArgAction::SetTrue) .long(CHECK_ASAN_LOG), - Arg::with_name(DISABLE_CHECK_DEBUGGER) - .takes_value(false) + Arg::new(DISABLE_CHECK_DEBUGGER) + .action(ArgAction::SetTrue) .long("disable_check_debugger"), ] } -pub fn args(name: &'static str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("test an application with a specific input") .args(&build_shared_args()) } diff --git a/src/agent/onefuzz-task/src/main.rs b/src/agent/onefuzz-task/src/main.rs index 25ddc1dc48..ad9bdb208c 100644 --- a/src/agent/onefuzz-task/src/main.rs +++ b/src/agent/onefuzz-task/src/main.rs @@ -10,7 +10,7 @@ extern crate onefuzz_telemetry; extern crate onefuzz; use anyhow::Result; -use clap::{App, ArgMatches, SubCommand}; +use clap::{ArgMatches, Command}; use std::io::{stdout, Write}; mod local; @@ -29,11 +29,11 @@ fn main() -> Result<()> { env!("GIT_VERSION") ); - let app = App::new("onefuzz-task") - .version(built_version.as_str()) + let app = Command::new("onefuzz-task") + .version(built_version) .subcommand(managed::cmd::args(MANAGED_CMD)) .subcommand(local::cmd::args(LOCAL_CMD)) - .subcommand(SubCommand::with_name(LICENSE_CMD).about("display third-party licenses")); + .subcommand(Command::new(LICENSE_CMD).about("display third-party licenses")); let matches = app.get_matches(); @@ -43,7 +43,7 @@ fn main() -> Result<()> { result } -async fn run(args: ArgMatches<'static>) -> Result<()> { +async fn run(args: ArgMatches) -> Result<()> { // It'd be best to initialize these environment vars in the same abstraction that // pulls in user-provided task vars that set the environment, e.g. `target_env`. // For now, just ensure that sanitizer environment vars will be inherited by child @@ -51,12 +51,10 @@ async fn run(args: ArgMatches<'static>) -> Result<()> { set_sanitizer_env_vars()?; match args.subcommand() { - (LICENSE_CMD, Some(_)) => licenses(), - (LOCAL_CMD, Some(sub)) => local::cmd::run(sub.to_owned()).await, - (MANAGED_CMD, Some(sub)) => managed::cmd::run(sub).await, - _ => { - anyhow::bail!("missing subcommand\nUSAGE: {}", args.usage()); - } + Some((LICENSE_CMD, _)) => licenses(), + Some((LOCAL_CMD, sub)) => local::cmd::run(sub.to_owned()).await, + Some((MANAGED_CMD, sub)) => managed::cmd::run(sub).await, + _ => anyhow::bail!("No command provided. Run with 'help' to see available commands."), } } diff --git a/src/agent/onefuzz-task/src/managed/cmd.rs b/src/agent/onefuzz-task/src/managed/cmd.rs index 7fbfc70c11..9e80ed7a0d 100644 --- a/src/agent/onefuzz-task/src/managed/cmd.rs +++ b/src/agent/onefuzz-task/src/managed/cmd.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use anyhow::Result; -use clap::{App, Arg, SubCommand}; +use clap::{Arg, Command}; use std::time::Duration; use crate::tasks::{ @@ -13,10 +13,17 @@ use crate::tasks::{ const OOM_CHECK_INTERVAL: Duration = Duration::from_secs(5); -pub async fn run(args: &clap::ArgMatches<'_>) -> Result<()> { +pub async fn run(args: &clap::ArgMatches) -> Result<()> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); - let config_path = value_t!(args, "config", PathBuf)?; - let setup_dir = value_t!(args, "setup_dir", PathBuf)?; + + let config_path = args + .get_one::("config") + .expect("marked as required"); + + let setup_dir = args + .get_one::("setup_dir") + .expect("marked as required"); + let config = Config::from_file(config_path, setup_dir)?; init_telemetry(config.common()).await; @@ -118,9 +125,17 @@ async fn init_telemetry(config: &CommonConfig) { .await; } -pub fn args(name: &str) -> App<'static, 'static> { - SubCommand::with_name(name) +pub fn args(name: &'static str) -> Command { + Command::new(name) .about("managed fuzzing") - .arg(Arg::with_name("config").required(true)) - .arg(Arg::with_name("setup_dir").required(true)) + .arg( + Arg::new("config") + .required(true) + .value_parser(value_parser!(PathBuf)), + ) + .arg( + Arg::new("setup_dir") + .required(true) + .value_parser(value_parser!(PathBuf)), + ) } diff --git a/src/agent/onefuzz-task/src/tasks/config.rs b/src/agent/onefuzz-task/src/tasks/config.rs index 6f22fbacff..585d23d7c1 100644 --- a/src/agent/onefuzz-task/src/tasks/config.rs +++ b/src/agent/onefuzz-task/src/tasks/config.rs @@ -17,7 +17,11 @@ use onefuzz_telemetry::{ }; use reqwest::Url; use serde::{self, Deserialize}; -use std::{path::PathBuf, sync::Arc, time::Duration}; +use std::{ + path::{Path, PathBuf}, + sync::Arc, + time::Duration, +}; use uuid::Uuid; const DEFAULT_MIN_AVAILABLE_MEMORY_MB: u64 = 100; @@ -135,13 +139,13 @@ pub enum Config { } impl Config { - pub fn from_file(path: PathBuf, setup_dir: PathBuf) -> Result { + pub fn from_file(path: &Path, setup_dir: &Path) -> Result { let json = std::fs::read_to_string(path)?; let json_config: serde_json::Value = serde_json::from_str(&json)?; // override the setup_dir in the config file with the parameter value if specified let mut config: Self = serde_json::from_value(json_config)?; - config.common_mut().setup_dir = setup_dir; + config.common_mut().setup_dir = setup_dir.to_owned(); Ok(config) } diff --git a/src/agent/onefuzz-task/src/tasks/utils.rs b/src/agent/onefuzz-task/src/tasks/utils.rs index 3d039cb8c5..02e56fb3d3 100644 --- a/src/agent/onefuzz-task/src/tasks/utils.rs +++ b/src/agent/onefuzz-task/src/tasks/utils.rs @@ -85,7 +85,7 @@ impl CheckNotify for tokio::sync::Notify { } } -pub fn parse_key_value(value: String) -> Result<(String, String)> { +pub fn parse_key_value(value: &str) -> Result<(String, String)> { let offset = value .find('=') .ok_or_else(|| format_err!("invalid key=value, no = found {:?}", value))?; diff --git a/src/agent/onefuzz/Cargo.toml b/src/agent/onefuzz/Cargo.toml index 286d8fd7c4..c0bb870ec7 100644 --- a/src/agent/onefuzz/Cargo.toml +++ b/src/agent/onefuzz/Cargo.toml @@ -60,8 +60,8 @@ nix = "0.25" [target.'cfg(target_os = "linux")'.dependencies] pete = "0.9" rstack = "0.3" -proc-maps = "0.2" +proc-maps = { version = "0.3", default-features = false } [dev-dependencies] -structopt = "0.3" +clap = { version = "4.1.6", features = ["derive"] } pretty_assertions = "1.3.0" diff --git a/src/agent/onefuzz/examples/dir-monitor.rs b/src/agent/onefuzz/examples/dir-monitor.rs index 203f11da5f..6922d5cd64 100644 --- a/src/agent/onefuzz/examples/dir-monitor.rs +++ b/src/agent/onefuzz/examples/dir-monitor.rs @@ -2,18 +2,18 @@ // Licensed under the MIT License. use anyhow::Result; +use clap::Parser; use onefuzz::monitor::DirectoryMonitor; -use structopt::StructOpt; -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] struct Opt { - #[structopt(short, long)] + #[arg(short, long)] path: String, } #[tokio::main] async fn main() -> Result<()> { - let opt = Opt::from_args(); + let opt = Opt::parse(); let mut monitor = DirectoryMonitor::new(opt.path).await?; monitor.set_report_directories(true); diff --git a/src/agent/onefuzz/examples/test-input.rs b/src/agent/onefuzz/examples/test-input.rs index bdc7bf4e8d..d834b5f854 100644 --- a/src/agent/onefuzz/examples/test-input.rs +++ b/src/agent/onefuzz/examples/test-input.rs @@ -4,40 +4,40 @@ use std::path::PathBuf; use anyhow::Result; +use clap::Parser; use onefuzz::{input_tester::Tester, machine_id::MachineIdentity}; -use structopt::StructOpt; -#[derive(Debug, PartialEq, Eq, StructOpt)] -#[structopt(name = "test-input")] +#[derive(Debug, PartialEq, Eq, Parser)] +#[command(name = "test-input")] struct Opt { - #[structopt(short, long)] + #[arg(short, long)] pub exe: PathBuf, - #[structopt(short, long, long_help = "Defaults to `{input}`")] + #[arg(short, long, long_help = "Defaults to `{input}`")] pub options: Vec, - #[structopt(short, long, long_help = "Defaults to dir of `exe`")] + #[arg(short, long, long_help = "Defaults to dir of `exe`")] pub setup_dir: Option, - #[structopt(short, long)] + #[arg(short, long)] pub input: PathBuf, - #[structopt(long)] + #[arg(long)] pub check_asan_log: bool, - #[structopt(long)] + #[arg(long)] pub check_asan_stderr: bool, - #[structopt(long)] + #[arg(long)] pub no_check_debugger: bool, - #[structopt(short, long, long_help = "Timeout (seconds)", default_value = "5")] + #[arg(short, long, long_help = "Timeout (seconds)", default_value = "5")] pub timeout: u64, } #[tokio::main] async fn main() -> Result<()> { - let opt = Opt::from_args(); + let opt = Opt::parse(); // Default `setup_dir` to base dir of let setup_dir = opt.setup_dir.clone().unwrap_or_else(|| { diff --git a/src/agent/srcview/Cargo.toml b/src/agent/srcview/Cargo.toml index d6ea13f46b..03a76f5276 100644 --- a/src/agent/srcview/Cargo.toml +++ b/src/agent/srcview/Cargo.toml @@ -17,5 +17,5 @@ regex = "1" serde = { version = "1", features = ["derive"] } quick-xml = "0.27" anyhow = "1.0" -structopt = "0.3" -env_logger = "0.9" +env_logger = "0.10" +clap = { version = "4.1.6", features = ["derive"] } diff --git a/src/agent/srcview/src/bin/srcview.rs b/src/agent/srcview/src/bin/srcview.rs index f8526465f3..7c9b84125a 100644 --- a/src/agent/srcview/src/bin/srcview.rs +++ b/src/agent/srcview/src/bin/srcview.rs @@ -2,13 +2,13 @@ // Licensed under the MIT License. use anyhow::{format_err, Context, Result}; +use clap::Parser; use srcview::{ModOff, Report, SrcLine, SrcView}; use std::fs::{self, OpenOptions}; use std::io::{stdout, BufWriter, Write}; use std::path::{Path, PathBuf}; -use structopt::StructOpt; -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Opt { Srcloc(SrcLocOpt), PdbPaths(PdbPathsOpt), @@ -18,17 +18,17 @@ enum Opt { } /// Print the file paths in the provided PDB -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] struct PdbPathsOpt { pdb_path: PathBuf, } /// Print modoffset file with file and source lines -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] struct SrcLocOpt { pdb_path: PathBuf, modoff_path: PathBuf, - #[structopt(long)] + #[arg(long)] module_name: Option, } @@ -45,30 +45,30 @@ struct SrcLocOpt { /// /// The XML report is written to either a file or stdout if the argument is /// a single dash. -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] struct CoberturaOpt { pdb_path: PathBuf, modoff_path: PathBuf, - #[structopt(default_value = "-")] + #[arg(default_value = "-")] output_path: String, - #[structopt(long)] + #[arg(long)] module_name: Option, /// regular expression that will be applied against the file paths from the /// srcview - #[structopt(long)] + #[arg(long)] include_regex: Option, /// search and replace regular expression that is applied to all file /// paths that will appear in the output report - #[structopt(long)] + #[arg(long)] filter_regex: Option, } fn main() -> Result<()> { env_logger::init(); - let opt = Opt::from_args(); + let opt = Opt::parse(); match opt { Opt::Srcloc(opts) => srcloc(opts)?, diff --git a/src/deny.toml b/src/deny.toml index 7097444d30..bbaeec0cec 100644 --- a/src/deny.toml +++ b/src/deny.toml @@ -16,8 +16,6 @@ unsound = "deny" yanked = "deny" ignore = [ "RUSTSEC-2022-0048", # xml-rs is unmaintained - "RUSTSEC-2021-0139", # ansi_term is unmaintained - "RUSTSEC-2021-0145", # waiting for clap upgrade; we are unaffected by the bug (no custom allocator) ] [bans] diff --git a/src/proxy-manager/Cargo.lock b/src/proxy-manager/Cargo.lock index e5f9cb79a4..6f701184c0 100644 --- a/src/proxy-manager/Cargo.lock +++ b/src/proxy-manager/Cargo.lock @@ -51,17 +51,6 @@ dependencies = [ "syn 1.0.76", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -145,13 +134,13 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.26" +version = "4.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" +checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" dependencies = [ - "atty", "bitflags", "clap_lex", + "is-terminal", "once_cell", "strsim", "termcolor", @@ -230,17 +219,38 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "flume" version = "0.10.9" @@ -418,15 +428,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.2.6" @@ -554,12 +555,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "ipnet" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "itoa" version = "0.4.8" @@ -589,9 +612,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "lock_api" @@ -700,7 +729,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -1044,6 +1073,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "ryu" version = "1.0.5" diff --git a/src/proxy-manager/Cargo.toml b/src/proxy-manager/Cargo.toml index 794aef933b..906594d5e8 100644 --- a/src/proxy-manager/Cargo.toml +++ b/src/proxy-manager/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT" [dependencies] anyhow = "1.0" clap = { version = "4", features = ["cargo", "string"] } -env_logger = "0.9" +env_logger = "0.10" futures = "0.3" reqwest = { version = "0.11", features = [ "json",