1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

dd: avoid infinite loop in Input::force_fill()

Avoid an infinite loop in `Input::force_fill()` when the input has
fewer bytes than are being requested to be read from the input.
This commit is contained in:
Jeffrey Finkelstein 2022-02-04 21:42:21 -05:00
parent 1f7c08d87b
commit 84d4f24b8c

View file

@ -80,8 +80,7 @@ impl Input<io::Stdin> {
}; };
if let Some(amt) = skip { if let Some(amt) = skip {
let mut buf = vec![BUF_INIT_BYTE; amt]; i.force_fill(amt.try_into().unwrap())
i.force_fill(&mut buf, amt)
.map_err_context(|| "failed to read input".to_string())?; .map_err_context(|| "failed to read input".to_string())?;
} }
@ -264,17 +263,19 @@ impl<R: Read> Input<R> {
}) })
} }
/// Force-fills a buffer, ignoring zero-length reads which would otherwise be /// Read the specified number of bytes from this reader.
/// interpreted as EOF. ///
/// Note: This will not return unless the source (eventually) produces /// On success, this method returns the number of bytes read. If
/// enough bytes to meet target_len. /// this reader has fewer than `n` bytes available, then it reads
fn force_fill(&mut self, buf: &mut [u8], target_len: usize) -> std::io::Result<usize> { /// as many as possible. In that case, this method returns a
let mut base_idx = 0; /// number less than `n`.
while base_idx < target_len { ///
base_idx += self.read(&mut buf[base_idx..target_len])?; /// # Errors
} ///
/// If there is a problem reading.
Ok(base_idx) fn force_fill(&mut self, n: u64) -> std::io::Result<usize> {
let mut buf = vec![];
self.take(n).read_to_end(&mut buf)
} }
} }