Skip to content

Commit 65b1a98

Browse files
Manishearthalexcrichton
authored andcommitted
Rollup merge of #22640 - sfackler:fix-take, r=alexcrichton
We can't call into the inner reader for a 0-byte read because that may end up blocking or returning an error. r? @alexcrichton
2 parents db04229 + b46e3ee commit 65b1a98

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

src/libstd/io/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,13 +669,33 @@ impl<T> Take<T> {
669669

670670
impl<T: Read> Read for Take<T> {
671671
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
672+
// Don't call into inner reader at all at EOF because it may still block
673+
if self.limit == 0 {
674+
return Ok(0);
675+
}
676+
672677
let max = cmp::min(buf.len() as u64, self.limit) as usize;
673678
let n = try!(self.inner.read(&mut buf[..max]));
674679
self.limit -= n as u64;
675680
Ok(n)
676681
}
677682
}
678683

684+
impl<T: BufRead> BufRead for Take<T> {
685+
fn fill_buf(&mut self) -> Result<&[u8]> {
686+
let buf = try!(self.inner.fill_buf());
687+
let cap = cmp::min(buf.len() as u64, self.limit) as usize;
688+
Ok(&buf[..cap])
689+
}
690+
691+
fn consume(&mut self, amt: usize) {
692+
// Don't let callers reset the limit by passing an overlarge value
693+
let amt = cmp::min(amt as u64, self.limit) as usize;
694+
self.limit -= amt as u64;
695+
self.inner.consume(amt);
696+
}
697+
}
698+
679699
/// An adaptor which will emit all read data to a specified writer as well.
680700
///
681701
/// For more information see `ReadExt::tee`
@@ -846,6 +866,7 @@ impl<B: BufRead> Iterator for Lines<B> {
846866
mod tests {
847867
use prelude::v1::*;
848868
use io::prelude::*;
869+
use io;
849870
use super::Cursor;
850871

851872
#[test]
@@ -943,4 +964,18 @@ mod tests {
943964
let mut v = String::new();
944965
assert!(c.read_to_string(&mut v).is_err());
945966
}
967+
968+
#[test]
969+
fn take_eof() {
970+
struct R;
971+
972+
impl Read for R {
973+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
974+
Err(io::Error::new(io::ErrorKind::Other, "", None))
975+
}
976+
}
977+
978+
let mut buf = [0; 1];
979+
assert_eq!(Ok(0), R.take(0).read(&mut buf));
980+
}
946981
}

0 commit comments

Comments
 (0)