Skip to content

Commit

Permalink
Fix io::Take behavior with limit 0
Browse files Browse the repository at this point in the history
We can't call into the inner reader for a 0-byte read because that may
end up blocking or returning an error.
  • Loading branch information
sfackler committed Feb 21, 2015
1 parent 522d09d commit 03753ba
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/libstd/io/mod.rs
Expand Up @@ -669,6 +669,11 @@ impl<T> Take<T> {

impl<T: Read> Read for Take<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
// Don't call into inner reader at all at EOF because it may still block
if self.limit == 0 {
return Ok(0);
}

let max = cmp::min(buf.len() as u64, self.limit) as usize;
let n = try!(self.inner.read(&mut buf[..max]));
self.limit -= n as u64;
Expand Down Expand Up @@ -846,6 +851,7 @@ impl<B: BufRead> Iterator for Lines<B> {
mod tests {
use prelude::v1::*;
use io::prelude::*;
use io;
use super::Cursor;

#[test]
Expand Down Expand Up @@ -943,4 +949,18 @@ mod tests {
let mut v = String::new();
assert!(c.read_to_string(&mut v).is_err());
}

#[test]
fn take_eof() {
struct R;

impl Read for R {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, "", None))
}
}

let mut buf = [0; 1];
assert_eq!(Ok(0), R.take(0).read(&mut buf));
}
}

0 comments on commit 03753ba

Please sign in to comment.