mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #5758 from sylvestre/fuzz-thread
fuzz: use thread to bypass the limitation of output
This commit is contained in:
commit
f3833bb652
2 changed files with 24 additions and 24 deletions
2
.github/workflows/fuzzing.yml
vendored
2
.github/workflows/fuzzing.yml
vendored
|
@ -48,7 +48,7 @@ jobs:
|
||||||
- { name: fuzz_expr, should_pass: true }
|
- { name: fuzz_expr, should_pass: true }
|
||||||
- { name: fuzz_printf, should_pass: false }
|
- { name: fuzz_printf, should_pass: false }
|
||||||
- { name: fuzz_echo, should_pass: true }
|
- { name: fuzz_echo, should_pass: true }
|
||||||
# - { name: fuzz_seq, should_pass: false }
|
- { name: fuzz_seq, should_pass: false }
|
||||||
- { name: fuzz_parse_glob, should_pass: true }
|
- { name: fuzz_parse_glob, should_pass: true }
|
||||||
- { name: fuzz_parse_size, should_pass: true }
|
- { name: fuzz_parse_size, should_pass: true }
|
||||||
- { name: fuzz_parse_time, should_pass: true }
|
- { name: fuzz_parse_time, should_pass: true }
|
||||||
|
|
|
@ -8,12 +8,12 @@ use libc::{close, dup, dup2, pipe, STDERR_FILENO, STDOUT_FILENO};
|
||||||
use rand::prelude::SliceRandom;
|
use rand::prelude::SliceRandom;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::io;
|
|
||||||
use std::io::{Seek, SeekFrom, Write};
|
use std::io::{Seek, SeekFrom, Write};
|
||||||
use std::os::fd::{AsRawFd, RawFd};
|
use std::os::fd::{AsRawFd, RawFd};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::{atomic::AtomicBool, Once};
|
use std::sync::{atomic::AtomicBool, Once};
|
||||||
|
use std::{io, thread};
|
||||||
|
|
||||||
/// Represents the result of running a command, including its standard output,
|
/// Represents the result of running a command, including its standard output,
|
||||||
/// standard error, and exit code.
|
/// standard error, and exit code.
|
||||||
|
@ -56,7 +56,7 @@ pub fn generate_and_run_uumain<F>(
|
||||||
pipe_input: Option<&str>,
|
pipe_input: Option<&str>,
|
||||||
) -> CommandResult
|
) -> CommandResult
|
||||||
where
|
where
|
||||||
F: FnOnce(std::vec::IntoIter<OsString>) -> i32,
|
F: FnOnce(std::vec::IntoIter<OsString>) -> i32 + Send + 'static,
|
||||||
{
|
{
|
||||||
// Duplicate the stdout and stderr file descriptors
|
// Duplicate the stdout and stderr file descriptors
|
||||||
let original_stdout_fd = unsafe { dup(STDOUT_FILENO) };
|
let original_stdout_fd = unsafe { dup(STDOUT_FILENO) };
|
||||||
|
@ -68,6 +68,7 @@ where
|
||||||
exit_code: -1,
|
exit_code: -1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Running test {:?}", &args[0..]);
|
println!("Running test {:?}", &args[0..]);
|
||||||
let mut pipe_stdout_fds = [-1; 2];
|
let mut pipe_stdout_fds = [-1; 2];
|
||||||
let mut pipe_stderr_fds = [-1; 2];
|
let mut pipe_stderr_fds = [-1; 2];
|
||||||
|
@ -120,10 +121,20 @@ where
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let uumain_exit_status = uumain_function(args.to_owned().into_iter());
|
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]));
|
||||||
|
let status = uumain_function(args.to_owned().into_iter());
|
||||||
io::stdout().flush().unwrap();
|
io::stdout().flush().unwrap();
|
||||||
io::stderr().flush().unwrap();
|
io::stderr().flush().unwrap();
|
||||||
|
unsafe {
|
||||||
|
close(pipe_stdout_fds[1]);
|
||||||
|
close(pipe_stderr_fds[1]);
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
close(STDERR_FILENO);
|
||||||
|
}
|
||||||
|
(status, out.join().unwrap(), err.join().unwrap())
|
||||||
|
});
|
||||||
|
|
||||||
// Restore the original stdout and stderr
|
// Restore the original stdout and stderr
|
||||||
if unsafe { dup2(original_stdout_fd, STDOUT_FILENO) } == -1
|
if unsafe { dup2(original_stdout_fd, STDOUT_FILENO) } == -1
|
||||||
|
@ -135,13 +146,6 @@ where
|
||||||
exit_code: -1,
|
exit_code: -1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
unsafe {
|
|
||||||
close(original_stdout_fd);
|
|
||||||
close(original_stderr_fd);
|
|
||||||
|
|
||||||
close(pipe_stdout_fds[1]);
|
|
||||||
close(pipe_stderr_fds[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore the original stdin if it was modified
|
// Restore the original stdin if it was modified
|
||||||
if let Some(fd) = original_stdin_fd {
|
if let Some(fd) = original_stdin_fd {
|
||||||
|
@ -155,18 +159,14 @@ where
|
||||||
unsafe { close(fd) };
|
unsafe { close(fd) };
|
||||||
}
|
}
|
||||||
|
|
||||||
let captured_stdout = read_from_fd(pipe_stdout_fds[0]).trim().to_string();
|
CommandResult {
|
||||||
let captured_stderr = read_from_fd(pipe_stderr_fds[0]).to_string();
|
stdout: captured_stdout,
|
||||||
let captured_stderr = captured_stderr
|
stderr: captured_stderr
|
||||||
.split_once(':')
|
.split_once(':')
|
||||||
.map(|x| x.1)
|
.map(|x| x.1)
|
||||||
.unwrap_or("")
|
.unwrap_or("")
|
||||||
.trim()
|
.trim()
|
||||||
.to_string();
|
.to_string(),
|
||||||
|
|
||||||
CommandResult {
|
|
||||||
stdout: captured_stdout,
|
|
||||||
stderr: captured_stderr,
|
|
||||||
exit_code: uumain_exit_status,
|
exit_code: uumain_exit_status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue