From cab687853a63198e5de9aa094d4ac01d068d0285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Paolacci?= Date: Mon, 16 Dec 2013 19:11:17 +0100 Subject: [PATCH 1/2] Make BufferedReader propagate 0-byte long reads. Could prevent callers from catching the situation and lead to e.g early iterator terminations (cf. `Reader::read_byte') since `None' is only to be returned only on EOF. --- src/libstd/io/buffered.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 95c313dd282..6350fabb018 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -118,14 +118,14 @@ impl Reader for BufferedReader { fn read(&mut self, buf: &mut [u8]) -> Option { let nread = { let available = self.fill(); - if available.len() == 0 { - return None; - } let nread = num::min(available.len(), buf.len()); vec::bytes::copy_memory(buf, available.slice_to(nread)); nread }; self.pos += nread; + if nread == 0 && self.inner.eof() && buf.len() != 0 { + return None; + } Some(nread) } From ee887d70780bce4c89a8977d04f724064ee1ae8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Paolacci?= Date: Sun, 22 Dec 2013 19:07:08 +0100 Subject: [PATCH 2/2] Add tests for 0-byte read propagation. The two `Some(0)' used to be `None' before the patch, a zero-byte long read exhausting a reader (and thereafter) still produce a `None'. --- src/libstd/io/buffered.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 6350fabb018..df52f036d46 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -322,6 +322,21 @@ mod test { fn write(&mut self, _: &[u8]) { } } + /// A dummy reader intended at testing short-reads propagation. + pub struct ShortReader { + priv lengths: ~[uint], + } + + impl Reader for ShortReader { + fn read(&mut self, _: &mut [u8]) -> Option { + self.lengths.shift_opt() + } + + fn eof(&mut self) -> bool { + self.lengths.len() == 0 + } + } + #[test] fn test_buffered_reader() { let inner = MemReader::new(~[0, 1, 2, 3, 4]); @@ -475,6 +490,19 @@ mod test { assert_eq!(it.next(), None); } + #[test] + fn test_short_reads() { + let inner = ShortReader{lengths: ~[0, 1, 2, 0, 1, 0]}; + let mut reader = BufferedReader::new(inner); + let mut buf = [0, 0]; + assert_eq!(reader.read(buf), Some(0)); + assert_eq!(reader.read(buf), Some(1)); + assert_eq!(reader.read(buf), Some(2)); + assert_eq!(reader.read(buf), Some(0)); + assert_eq!(reader.read(buf), Some(1)); + assert_eq!(reader.read(buf), None); + } + #[bench] fn bench_buffered_reader(bh: &mut Harness) {