mcookie - fix providing /dev/random or /dev/urandom as file leads to infinite loop (#274)
* Update mcookie.rs * edit doc * fmt * fix for unix and non-unix build * add test case * refactor * fmt * fix
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::unix::fs::FileTypeExt;
|
||||||
use std::{fs::File, io::Read};
|
use std::{fs::File, io::Read};
|
||||||
|
|
||||||
use clap::{crate_version, Arg, ArgAction, Command};
|
use clap::{crate_version, Arg, ArgAction, Command};
|
||||||
@@ -56,9 +58,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||||||
if let Some(max_bytes) = &max_size {
|
if let Some(max_bytes) = &max_size {
|
||||||
let mut handle = f.take(*max_bytes);
|
let mut handle = f.take(*max_bytes);
|
||||||
handle.read_to_end(&mut buffer)?;
|
handle.read_to_end(&mut buffer)?;
|
||||||
|
} else {
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
const DEFAULT_SEED_READ_BYTES: u64 = 1024;
|
||||||
|
let metadata = f.metadata()?;
|
||||||
|
|
||||||
|
if metadata.file_type().is_char_device() {
|
||||||
|
let mut handle = f.take(DEFAULT_SEED_READ_BYTES);
|
||||||
|
handle.read_to_end(&mut buffer)?;
|
||||||
} else {
|
} else {
|
||||||
f.read_to_end(&mut buffer)?;
|
f.read_to_end(&mut buffer)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
{
|
||||||
|
f.read_to_end(&mut buffer)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
eprintln!("Got {} bytes from {}", buffer.len(), file);
|
eprintln!("Got {} bytes from {}", buffer.len(), file);
|
||||||
|
|||||||
@@ -64,6 +64,31 @@ fn test_seed_files_and_max_size_raw() {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(unix)] // Character devices like /dev/zero are a Unix concept
|
||||||
|
fn test_char_device_input() {
|
||||||
|
let res_no_limit = new_ucmd!().arg("-f").arg("/dev/zero").succeeds();
|
||||||
|
|
||||||
|
let stdout_no_limit = res_no_limit.no_stderr().stdout_str().trim_end();
|
||||||
|
assert_eq!(stdout_no_limit.len(), 32);
|
||||||
|
assert!(stdout_no_limit.chars().all(|c| c.is_ascii_hexdigit()));
|
||||||
|
|
||||||
|
let res_verbose = new_ucmd!()
|
||||||
|
.arg("--verbose")
|
||||||
|
.arg("-f")
|
||||||
|
.arg("/dev/zero")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
res_verbose.stderr_contains("Got 1024 bytes from /dev/zero");
|
||||||
|
res_verbose.stderr_contains("Got 128 bytes from randomness source"); // Ensure internal randomness is still added
|
||||||
|
|
||||||
|
let stdout_verbose = res_verbose.stdout_str().trim_end();
|
||||||
|
assert_eq!(stdout_verbose.len(), 32);
|
||||||
|
assert!(stdout_verbose.chars().all(|c| c.is_ascii_hexdigit()));
|
||||||
|
|
||||||
|
assert_ne!(stdout_no_limit, stdout_verbose);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_seed_files_and_max_size_human_readable() {
|
fn test_seed_files_and_max_size_human_readable() {
|
||||||
let mut file = NamedTempFile::new().unwrap();
|
let mut file = NamedTempFile::new().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user