From 75072b5a981979c7b950156de815c569a77477d4 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 8 Apr 2025 17:30:43 +0200 Subject: [PATCH 1/3] fuzz: Run cargo fmt --- fuzz/fuzz_targets/fuzz_cksum.rs | 5 +++-- fuzz/fuzz_targets/fuzz_common/mod.rs | 6 +++--- fuzz/fuzz_targets/fuzz_common/pretty_print.rs | 2 +- fuzz/fuzz_targets/fuzz_cut.rs | 2 +- fuzz/fuzz_targets/fuzz_echo.rs | 2 +- fuzz/fuzz_targets/fuzz_env.rs | 2 +- fuzz/fuzz_targets/fuzz_expr.rs | 2 +- fuzz/fuzz_targets/fuzz_printf.rs | 2 +- fuzz/fuzz_targets/fuzz_split.rs | 2 +- fuzz/fuzz_targets/fuzz_test.rs | 2 +- fuzz/fuzz_targets/fuzz_tr.rs | 2 +- fuzz/fuzz_targets/fuzz_wc.rs | 2 +- 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/fuzz/fuzz_targets/fuzz_cksum.rs b/fuzz/fuzz_targets/fuzz_cksum.rs index c14457ab2..5e7f0775e 100644 --- a/fuzz/fuzz_targets/fuzz_cksum.rs +++ b/fuzz/fuzz_targets/fuzz_cksum.rs @@ -10,9 +10,10 @@ use std::ffi::OsString; use uu_cksum::uumain; mod fuzz_common; use crate::fuzz_common::{ - compare_result, generate_and_run_uumain, generate_random_file, generate_random_string, + CommandResult, compare_result, generate_and_run_uumain, generate_random_file, + generate_random_string, pretty_print::{print_or_empty, print_test_begin}, - replace_fuzz_binary_name, run_gnu_cmd, CommandResult, + replace_fuzz_binary_name, run_gnu_cmd, }; use rand::Rng; use std::env::temp_dir; diff --git a/fuzz/fuzz_targets/fuzz_common/mod.rs b/fuzz/fuzz_targets/fuzz_common/mod.rs index 4bd801edb..79abe4645 100644 --- a/fuzz/fuzz_targets/fuzz_common/mod.rs +++ b/fuzz/fuzz_targets/fuzz_common/mod.rs @@ -5,12 +5,12 @@ use console::Style; use libc::STDIN_FILENO; -use libc::{close, dup, dup2, pipe, STDERR_FILENO, STDOUT_FILENO}; +use libc::{STDERR_FILENO, STDOUT_FILENO, close, dup, dup2, pipe}; use pretty_print::{ print_diff, print_end_with_status, print_or_empty, print_section, print_with_style, }; -use rand::prelude::IndexedRandom; use rand::Rng; +use rand::prelude::IndexedRandom; use std::env::temp_dir; use std::ffi::OsString; use std::fs::File; @@ -18,7 +18,7 @@ use std::io::{Seek, SeekFrom, Write}; use std::os::fd::{AsRawFd, RawFd}; use std::process::{Command, Stdio}; use std::sync::atomic::Ordering; -use std::sync::{atomic::AtomicBool, Once}; +use std::sync::{Once, atomic::AtomicBool}; use std::{io, thread}; pub mod pretty_print; diff --git a/fuzz/fuzz_targets/fuzz_common/pretty_print.rs b/fuzz/fuzz_targets/fuzz_common/pretty_print.rs index c0dd71150..373094ad4 100644 --- a/fuzz/fuzz_targets/fuzz_common/pretty_print.rs +++ b/fuzz/fuzz_targets/fuzz_common/pretty_print.rs @@ -5,7 +5,7 @@ use std::fmt; -use console::{style, Style}; +use console::{Style, style}; use similar::TextDiff; pub fn print_section(s: S) { diff --git a/fuzz/fuzz_targets/fuzz_cut.rs b/fuzz/fuzz_targets/fuzz_cut.rs index b664def65..828a7c619 100644 --- a/fuzz/fuzz_targets/fuzz_cut.rs +++ b/fuzz/fuzz_targets/fuzz_cut.rs @@ -13,7 +13,7 @@ use std::ffi::OsString; mod fuzz_common; use crate::fuzz_common::{ - compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, + CommandResult, compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, }; static CMD_PATH: &str = "cut"; diff --git a/fuzz/fuzz_targets/fuzz_echo.rs b/fuzz/fuzz_targets/fuzz_echo.rs index 138e84964..a36a7ebad 100644 --- a/fuzz/fuzz_targets/fuzz_echo.rs +++ b/fuzz/fuzz_targets/fuzz_echo.rs @@ -2,8 +2,8 @@ use libfuzzer_sys::fuzz_target; use uu_echo::uumain; -use rand::prelude::IndexedRandom; use rand::Rng; +use rand::prelude::IndexedRandom; use std::ffi::OsString; mod fuzz_common; diff --git a/fuzz/fuzz_targets/fuzz_env.rs b/fuzz/fuzz_targets/fuzz_env.rs index 3b8e0185d..f38dced07 100644 --- a/fuzz/fuzz_targets/fuzz_env.rs +++ b/fuzz/fuzz_targets/fuzz_env.rs @@ -12,7 +12,7 @@ use std::ffi::OsString; mod fuzz_common; use crate::fuzz_common::{ - compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, + CommandResult, compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, }; use rand::Rng; diff --git a/fuzz/fuzz_targets/fuzz_expr.rs b/fuzz/fuzz_targets/fuzz_expr.rs index ca365b878..b1a650f42 100644 --- a/fuzz/fuzz_targets/fuzz_expr.rs +++ b/fuzz/fuzz_targets/fuzz_expr.rs @@ -8,8 +8,8 @@ use libfuzzer_sys::fuzz_target; use uu_expr::uumain; -use rand::prelude::IndexedRandom; use rand::Rng; +use rand::prelude::IndexedRandom; use std::{env, ffi::OsString}; mod fuzz_common; diff --git a/fuzz/fuzz_targets/fuzz_printf.rs b/fuzz/fuzz_targets/fuzz_printf.rs index a3eb67dd0..e8d74e2be 100644 --- a/fuzz/fuzz_targets/fuzz_printf.rs +++ b/fuzz/fuzz_targets/fuzz_printf.rs @@ -8,8 +8,8 @@ use libfuzzer_sys::fuzz_target; use uu_printf::uumain; -use rand::seq::IndexedRandom; use rand::Rng; +use rand::seq::IndexedRandom; use std::env; use std::ffi::OsString; diff --git a/fuzz/fuzz_targets/fuzz_split.rs b/fuzz/fuzz_targets/fuzz_split.rs index d3c11a2ae..9a925b222 100644 --- a/fuzz/fuzz_targets/fuzz_split.rs +++ b/fuzz/fuzz_targets/fuzz_split.rs @@ -13,7 +13,7 @@ use std::ffi::OsString; mod fuzz_common; use crate::fuzz_common::{ - compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, + CommandResult, compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, }; static CMD_PATH: &str = "split"; diff --git a/fuzz/fuzz_targets/fuzz_test.rs b/fuzz/fuzz_targets/fuzz_test.rs index 4aa91ee9f..afa78ecf4 100644 --- a/fuzz/fuzz_targets/fuzz_test.rs +++ b/fuzz/fuzz_targets/fuzz_test.rs @@ -8,8 +8,8 @@ use libfuzzer_sys::fuzz_target; use uu_test::uumain; -use rand::prelude::IndexedRandom; use rand::Rng; +use rand::prelude::IndexedRandom; use std::ffi::OsString; mod fuzz_common; diff --git a/fuzz/fuzz_targets/fuzz_tr.rs b/fuzz/fuzz_targets/fuzz_tr.rs index 0d86542e8..d260e3780 100644 --- a/fuzz/fuzz_targets/fuzz_tr.rs +++ b/fuzz/fuzz_targets/fuzz_tr.rs @@ -12,7 +12,7 @@ use rand::Rng; mod fuzz_common; use crate::fuzz_common::{ - compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, + CommandResult, compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, }; static CMD_PATH: &str = "tr"; diff --git a/fuzz/fuzz_targets/fuzz_wc.rs b/fuzz/fuzz_targets/fuzz_wc.rs index 8f5f7844e..39dfb1ee8 100644 --- a/fuzz/fuzz_targets/fuzz_wc.rs +++ b/fuzz/fuzz_targets/fuzz_wc.rs @@ -13,7 +13,7 @@ use std::ffi::OsString; mod fuzz_common; use crate::fuzz_common::{ - compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, + CommandResult, compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, }; static CMD_PATH: &str = "wc"; From 2caeaf511ed02832e3c9ba450311ebb409ff9450 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 8 Apr 2025 17:38:33 +0200 Subject: [PATCH 2/3] fuzz: Run cargo clippy Unfortunately, cargo clippy fails when testing fuzz_seq_parse_number: ``` error[E0603]: module `number` is private --> fuzz_targets/fuzz_seq_parse_number.rs:9:13 | 9 | use uu_seq::number::PreciseNumber; | ^^^^^^ private module | note: the module `number` is defined here --> /home/drinkcat/dev/coreutils/coreutils/src/uu/seq/src/seq.rs:24:1 | 24 | mod number; | ^^^^^^^^^^ ``` But we can still fix the rest... --- fuzz/fuzz_targets/fuzz_common/mod.rs | 4 ++++ fuzz/fuzz_targets/fuzz_common/pretty_print.rs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fuzz/fuzz_targets/fuzz_common/mod.rs b/fuzz/fuzz_targets/fuzz_common/mod.rs index 79abe4645..04910635e 100644 --- a/fuzz/fuzz_targets/fuzz_common/mod.rs +++ b/fuzz/fuzz_targets/fuzz_common/mod.rs @@ -132,6 +132,8 @@ where let (uumain_exit_status, captured_stdout, captured_stderr) = thread::scope(|s| { let out = s.spawn(|| read_from_fd(pipe_stdout_fds[0])); let err = s.spawn(|| read_from_fd(pipe_stderr_fds[0])); + #[allow(clippy::unnecessary_to_owned)] + // TODO: clippy wants us to use args.iter().cloned() ? let status = uumain_function(args.to_owned().into_iter()); // Reset the exit code global variable in case we run another test after this one // See https://github.com/uutils/coreutils/issues/5777 @@ -409,6 +411,7 @@ pub fn generate_random_string(max_length: usize) -> String { result } +#[allow(dead_code)] pub fn generate_random_file() -> Result { let mut rng = rand::rng(); let file_name: String = (0..10) @@ -429,6 +432,7 @@ pub fn generate_random_file() -> Result { Ok(file_path.to_str().unwrap().to_string()) } +#[allow(dead_code)] pub fn replace_fuzz_binary_name(cmd: &str, result: &mut CommandResult) { let fuzz_bin_name = format!("fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_{cmd}"); diff --git a/fuzz/fuzz_targets/fuzz_common/pretty_print.rs b/fuzz/fuzz_targets/fuzz_common/pretty_print.rs index 373094ad4..a0e322429 100644 --- a/fuzz/fuzz_targets/fuzz_common/pretty_print.rs +++ b/fuzz/fuzz_targets/fuzz_common/pretty_print.rs @@ -16,6 +16,7 @@ pub fn print_subsection(s: S) { println!("{}", style(format!("--- {}", s)).bright()); } +#[allow(dead_code)] pub fn print_test_begin(msg: S) { println!( "{} {} {}", @@ -50,7 +51,7 @@ pub fn print_with_style(msg: S, style: Style) { println!("{}", style.apply_to(msg)); } -pub fn print_diff<'a, 'b>(got: &'a str, expected: &'b str) { +pub fn print_diff(got: &str, expected: &str) { let diff = TextDiff::from_lines(got, expected); print_subsection("START diff"); From 8f9bdf36fd006a9f2303d19a9cdd5fef67521efb Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Wed, 9 Apr 2025 21:00:24 +0200 Subject: [PATCH 3/3] workflows/fuzzing.yml: Add timeout equal to total run time Just in case some of the values cause an infinite loop (or at least take a _very_ long time, see #7708), timeout, with the same duration as the maximum total fuzzing time. That'll allow us to _see_ what input causes the infinite loop. --- .github/workflows/fuzzing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml index c7d219733..2f7da429c 100644 --- a/.github/workflows/fuzzing.yml +++ b/.github/workflows/fuzzing.yml @@ -84,7 +84,7 @@ jobs: shell: bash continue-on-error: ${{ !matrix.test-target.name.should_pass }} run: | - cargo +nightly fuzz run ${{ matrix.test-target.name }} -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + cargo +nightly fuzz run ${{ matrix.test-target.name }} -- -max_total_time=${{ env.RUN_FOR }} -timeout=${{ env.RUN_FOR }} -detect_leaks=0 - name: Save Corpus Cache uses: actions/cache/save@v4 with: