diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index bb938c73d..8a73eb1f1 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -406,9 +406,10 @@ fn wipe_file( )); } + let metadata = fs::metadata(path).map_err_context(String::new)?; + // If force is true, set file permissions to not-readonly. if force { - let metadata = fs::metadata(path).map_err_context(String::new)?; let mut perms = metadata.permissions(); #[cfg(unix)] #[allow(clippy::useless_conversion, clippy::unnecessary_cast)] @@ -428,35 +429,37 @@ fn wipe_file( // Fill up our pass sequence let mut pass_sequence = Vec::new(); + if metadata.len() != 0 { + // Only add passes if the file is non-empty - if n_passes <= 3 { - // Only random passes if n_passes <= 3 - for _ in 0..n_passes { - pass_sequence.push(PassType::Random); - } - } else { - // First fill it with Patterns, shuffle it, then evenly distribute Random - let n_full_arrays = n_passes / PATTERNS.len(); // How many times can we go through all the patterns? - let remainder = n_passes % PATTERNS.len(); // How many do we get through on our last time through? + if n_passes <= 3 { + // Only random passes if n_passes <= 3 + for _ in 0..n_passes { + pass_sequence.push(PassType::Random); + } + } else { + // First fill it with Patterns, shuffle it, then evenly distribute Random + let n_full_arrays = n_passes / PATTERNS.len(); // How many times can we go through all the patterns? + let remainder = n_passes % PATTERNS.len(); // How many do we get through on our last time through? - for _ in 0..n_full_arrays { - for p in PATTERNS { - pass_sequence.push(PassType::Pattern(p)); + for _ in 0..n_full_arrays { + for p in PATTERNS { + pass_sequence.push(PassType::Pattern(p)); + } + } + for pattern in PATTERNS.into_iter().take(remainder) { + pass_sequence.push(PassType::Pattern(pattern)); + } + let mut rng = rand::thread_rng(); + pass_sequence.shuffle(&mut rng); // randomize the order of application + + let n_random = 3 + n_passes / 10; // Minimum 3 random passes; ratio of 10 after + // Evenly space random passes; ensures one at the beginning and end + for i in 0..n_random { + pass_sequence[i * (n_passes - 1) / (n_random - 1)] = PassType::Random; } } - for pattern in PATTERNS.into_iter().take(remainder) { - pass_sequence.push(PassType::Pattern(pattern)); - } - let mut rng = rand::thread_rng(); - pass_sequence.shuffle(&mut rng); // randomize the order of application - - let n_random = 3 + n_passes / 10; // Minimum 3 random passes; ratio of 10 after - // Evenly space random passes; ensures one at the beginning and end - for i in 0..n_random { - pass_sequence[i * (n_passes - 1) / (n_random - 1)] = PassType::Random; - } } - // --zero specifies whether we want one final pass of 0x00 on our file if zero { pass_sequence.push(PassType::Pattern(PATTERNS[0])); diff --git a/tests/by-util/test_shred.rs b/tests/by-util/test_shred.rs index d5de7882f..03aeef0c4 100644 --- a/tests/by-util/test_shred.rs +++ b/tests/by-util/test_shred.rs @@ -143,3 +143,23 @@ fn test_hex() { ucmd.arg("--size=0x10").arg(file).succeeds(); } + +#[test] +fn test_shred_empty() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let file_a = "test_shred_remove_a"; + + at.touch(file_a); + + // Shred file_a and verify that, as it is empty, it doesn't have "pass 1/3 (random)" + scene + .ucmd() + .arg("-uv") + .arg(file_a) + .succeeds() + .stdout_does_not_contain("pass 1/3 (random)"); + + assert!(!at.file_exists(file_a)); +}