diff options
| author | Steve Klabnik <steve@steveklabnik.com> | 2016-04-14 14:49:09 -0400 |
|---|---|---|
| committer | Steve Klabnik <steve@steveklabnik.com> | 2016-04-14 14:49:09 -0400 |
| commit | 78ab18199d69bcc801668bfbeea8190b2c73a939 (patch) | |
| tree | 78396f9da92b61c2cec5faad8589f71dc7fa0d33 | |
| parent | 04b7427bb19c6977e308a3523a7d0f3512471c1d (diff) | |
| parent | a3329f5452b20fd611537e7db1a86a9fe115008a (diff) | |
| download | rust-78ab18199d69bcc801668bfbeea8190b2c73a939.tar.gz rust-78ab18199d69bcc801668bfbeea8190b2c73a939.zip | |
Rollup merge of #32855 - troplin:take-bufread-fix, r=alexcrichton
Don't read past limit for in BufRead instance of Take Similar to `Read::read`, `BufRead::fill_buf` impl of `Take` should not call `inner.fill_buf` if the limit is already reached.
| -rw-r--r-- | src/libstd/io/mod.rs | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 6dd7273c17f..d914d143e70 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1505,6 +1505,11 @@ impl<T: Read> Read for Take<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: BufRead> BufRead for Take<T> { fn fill_buf(&mut self) -> Result<&[u8]> { + // Don't call into inner reader at all at EOF because it may still block + if self.limit == 0 { + return Ok(&[]); + } + let buf = self.inner.fill_buf()?; let cap = cmp::min(buf.len() as u64, self.limit) as usize; Ok(&buf[..cap]) @@ -1860,9 +1865,16 @@ mod tests { Err(io::Error::new(io::ErrorKind::Other, "")) } } + impl BufRead for R { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + Err(io::Error::new(io::ErrorKind::Other, "")) + } + fn consume(&mut self, _amt: usize) { } + } let mut buf = [0; 1]; assert_eq!(0, R.take(0).read(&mut buf).unwrap()); + assert_eq!(b"", R.take(0).fill_buf().unwrap()); } fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) { |
