Skip to content

Commit a4ad654

Browse files
committed
wip: add more checks
1 parent a74b7ea commit a4ad654

File tree

3 files changed

+75
-12
lines changed

3 files changed

+75
-12
lines changed

src/uu/shred/src/shred.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,17 +200,22 @@ impl BytesWriter {
200200
}
201201
}
202202

203-
fn bytes_for_pass(&mut self, size: usize) -> &[u8] {
203+
fn bytes_for_pass(&mut self, size: usize) -> Result<&[u8], std::io::Error> {
204204
match self {
205205
Self::Random { rng, buffer } => {
206206
let bytes = &mut buffer[..size];
207-
rng.fill(bytes);
208-
bytes
207+
match rng.try_fill(bytes) {
208+
Ok(()) => Ok(bytes),
209+
Err(err) => Err(std::io::Error::new(
210+
std::io::ErrorKind::Other,
211+
err.to_string(),
212+
)),
213+
}
209214
}
210215
Self::Pattern { offset, buffer } => {
211216
let bytes = &buffer[*offset..size + *offset];
212217
*offset = (*offset + size) % PATTERN_LENGTH;
213-
bytes
218+
Ok(bytes)
214219
}
215220
}
216221
}
@@ -237,8 +242,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
237242
None => unreachable!(),
238243
};
239244

240-
// TODO: implement --random-source
241-
242245
let remove_method = if matches.get_flag(options::WIPESYNC) {
243246
RemoveMethod::WipeSync
244247
} else if matches.contains_id(options::REMOVE) {
@@ -504,6 +507,29 @@ fn wipe_file(
504507
None => metadata.len(),
505508
};
506509

510+
// Random source errors
511+
if let Some(random_source_str) = random_source {
512+
let random_source_path = Path::new(random_source_str.as_str());
513+
if !random_source_path.exists() {
514+
return Err(USimpleError::new(
515+
1,
516+
format!(
517+
"{}: No such file or directory",
518+
random_source_path.maybe_quote()
519+
),
520+
));
521+
}
522+
if !random_source_path.is_file() {
523+
return Err(USimpleError::new(
524+
1,
525+
format!(
526+
"{}: read error: Is a directory",
527+
random_source_path.maybe_quote()
528+
),
529+
));
530+
}
531+
}
532+
507533
for (i, pass_type) in pass_sequence.into_iter().enumerate() {
508534
if verbose {
509535
let pass_name = pass_name(&pass_type);
@@ -517,7 +543,7 @@ fn wipe_file(
517543
}
518544
// size is an optional argument for exactly how many bytes we want to shred
519545
// Ignore failed writes; just keep trying
520-
show_if_err!(do_pass(&mut file, &pass_type, exact, size)
546+
show_if_err!(do_pass(&mut file, &pass_type, exact, size, random_source)
521547
.map_err_context(|| format!("{}: File write pass failed", path.maybe_quote())));
522548
}
523549

@@ -534,6 +560,7 @@ fn do_pass(
534560
pass_type: &PassType,
535561
exact: bool,
536562
file_size: u64,
563+
random_source: &Option<String>,
537564
) -> Result<(), io::Error> {
538565
// We might be at the end of the file due to a previous iteration, so rewind.
539566
file.rewind()?;
@@ -542,7 +569,15 @@ fn do_pass(
542569

543570
// We start by writing BLOCK_SIZE times as many time as possible.
544571
for _ in 0..(file_size / BLOCK_SIZE as u64) {
545-
let block = writer.bytes_for_pass(BLOCK_SIZE);
572+
let data = writer.bytes_for_pass(BLOCK_SIZE);
573+
let Ok(block) = data else {
574+
let random_source_path = random_source
575+
.clone()
576+
.expect("random_source should be Some is None");
577+
let path = Path::new(&random_source_path);
578+
show_error!("{}: end of file", path.maybe_quote());
579+
std::process::exit(1);
580+
};
546581
file.write_all(block)?;
547582
}
548583

@@ -551,7 +586,15 @@ fn do_pass(
551586
let bytes_left = (file_size % BLOCK_SIZE as u64) as usize;
552587
if bytes_left > 0 {
553588
let size = if exact { bytes_left } else { BLOCK_SIZE };
554-
let block = writer.bytes_for_pass(size);
589+
let data = writer.bytes_for_pass(size);
590+
let Ok(block) = data else {
591+
let random_source_path = random_source
592+
.clone()
593+
.expect("random_source should be Some is None");
594+
let path = Path::new(&random_source_path);
595+
show_error!("{}: end of file", path.maybe_quote());
596+
std::process::exit(1);
597+
};
555598
file.write_all(block)?;
556599
}
557600

src/uu/stdbuf/src/libstdbuf/build.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
use cpp_build::Config;
88

99
fn main() {
10-
Config::new().pic(true).build("src/libstdbuf.rs");
10+
Config::new()
11+
.compiler("clang++")
12+
.pic(true)
13+
.build("src/libstdbuf.rs");
1114
}

tests/by-util/test_shred.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,36 @@ fn test_shred_empty() {
183183

184184
#[test]
185185
fn test_random_source() {
186-
let (at, mut ucmd) = at_and_ucmd!();
186+
let scene = TestScenario::new(util_name!());
187+
let at = &scene.fixtures;
187188

188189
let file = "test_random_source";
189190
let file_original_content = "test_shred file content";
190191

191192
at.write(file, file_original_content);
192193

194+
// File is missing
195+
scene
196+
.ucmd()
197+
.arg("--random-source=test_random_file")
198+
.arg(file)
199+
.succeeds();
200+
193201
// Write to random file
194202
let random_file = "test_random_file";
195203
at.touch(random_file);
204+
205+
scene
206+
.ucmd()
207+
.arg("--random-source=test_random_file")
208+
.arg(file)
209+
.succeeds();
210+
196211
at.write(random_file, "random contents");
197212

198-
ucmd.arg("--random-source=test_random_file")
213+
scene
214+
.ucmd()
215+
.arg("--random-source=test_random_file")
199216
.arg(file)
200217
.succeeds();
201218

0 commit comments

Comments
 (0)