From 84d4f24b8c0e2d1dd24b6319ba37ea0fcb90a9e8 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Fri, 4 Feb 2022 21:42:21 -0500 Subject: [PATCH] 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. --- src/uu/dd/src/dd.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 54e3190ce..ac7b50d1b 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -80,8 +80,7 @@ impl Input { }; if let Some(amt) = skip { - let mut buf = vec![BUF_INIT_BYTE; amt]; - i.force_fill(&mut buf, amt) + i.force_fill(amt.try_into().unwrap()) .map_err_context(|| "failed to read input".to_string())?; } @@ -264,17 +263,19 @@ impl Input { }) } - /// Force-fills a buffer, ignoring zero-length reads which would otherwise be - /// interpreted as EOF. - /// Note: This will not return unless the source (eventually) produces - /// enough bytes to meet target_len. - fn force_fill(&mut self, buf: &mut [u8], target_len: usize) -> std::io::Result { - let mut base_idx = 0; - while base_idx < target_len { - base_idx += self.read(&mut buf[base_idx..target_len])?; - } - - Ok(base_idx) + /// Read the specified number of bytes from this reader. + /// + /// On success, this method returns the number of bytes read. If + /// this reader has fewer than `n` bytes available, then it reads + /// as many as possible. In that case, this method returns a + /// number less than `n`. + /// + /// # Errors + /// + /// If there is a problem reading. + fn force_fill(&mut self, n: u64) -> std::io::Result { + let mut buf = vec![]; + self.take(n).read_to_end(&mut buf) } }