1010
1111//! Readers and Writers for in-memory buffers
1212
13- use cmp:: max;
1413use cmp:: min;
1514use container:: Container ;
1615use option:: None ;
@@ -20,6 +19,25 @@ use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
2019use vec;
2120use vec:: { Vector , ImmutableVector , MutableVector , OwnedCloneableVector } ;
2221
22+ fn combine ( seek : SeekStyle , cur : uint , end : uint , offset : i64 ) -> IoResult < u64 > {
23+ // compute offset as signed and clamp to prevent overflow
24+ let pos = match seek {
25+ SeekSet => 0 ,
26+ SeekEnd => end,
27+ SeekCur => cur,
28+ } as i64 ;
29+
30+ if offset + pos < 0 {
31+ Err ( IoError {
32+ kind : io:: InvalidInput ,
33+ desc : "invalid seek to a negative offset" ,
34+ detail : None
35+ } )
36+ } else {
37+ Ok ( ( offset + pos) as u64 )
38+ }
39+ }
40+
2341/// Writes to an owned, growable byte vector
2442///
2543/// # Example
@@ -92,19 +110,11 @@ impl Writer for MemWriter {
92110 }
93111}
94112
95- // FIXME(#10432)
96113impl Seek for MemWriter {
97114 fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
98-
99115 fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
100- // compute offset as signed and clamp to prevent overflow
101- let offset = match style {
102- SeekSet => { 0 }
103- SeekEnd => { self . buf . len ( ) }
104- SeekCur => { self . pos }
105- } as i64 ;
106-
107- self . pos = max ( 0 , offset+pos) as uint ;
116+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
117+ self . pos = new as uint ;
108118 Ok ( ( ) )
109119 }
110120}
@@ -139,7 +149,7 @@ impl MemReader {
139149 /// Tests whether this reader has read all bytes in its buffer.
140150 ///
141151 /// If `true`, then this will no longer return bytes from `read`.
142- pub fn eof ( & self ) -> bool { self . pos = = self . buf . len ( ) }
152+ pub fn eof ( & self ) -> bool { self . pos > = self . buf . len ( ) }
143153
144154 /// Acquires an immutable reference to the underlying buffer of this
145155 /// `MemReader`.
@@ -172,7 +182,11 @@ impl Reader for MemReader {
172182
173183impl Seek for MemReader {
174184 fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
175- fn seek ( & mut self , _pos : i64 , _style : SeekStyle ) -> IoResult < ( ) > { fail ! ( ) }
185+ fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
186+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
187+ self . pos = new as uint ;
188+ Ok ( ( ) )
189+ }
176190}
177191
178192impl Buffer for MemReader {
@@ -236,24 +250,15 @@ impl<'a> Writer for BufWriter<'a> {
236250 }
237251}
238252
239- // FIXME(#10432)
240253impl < ' a > Seek for BufWriter < ' a > {
241254 fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
242-
243255 fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
244- // compute offset as signed and clamp to prevent overflow
245- let offset = match style {
246- SeekSet => { 0 }
247- SeekEnd => { self . buf . len ( ) }
248- SeekCur => { self . pos }
249- } as i64 ;
250-
251- self . pos = max ( 0 , offset+pos) as uint ;
256+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
257+ self . pos = new as uint ;
252258 Ok ( ( ) )
253259 }
254260}
255261
256-
257262/// Reads from a fixed-size byte slice
258263///
259264/// # Example
@@ -284,7 +289,7 @@ impl<'a> BufReader<'a> {
284289 /// Tests whether this reader has read all bytes in its buffer.
285290 ///
286291 /// If `true`, then this will no longer return bytes from `read`.
287- pub fn eof ( & self ) -> bool { self . pos = = self . buf . len ( ) }
292+ pub fn eof ( & self ) -> bool { self . pos > = self . buf . len ( ) }
288293}
289294
290295impl < ' a > Reader for BufReader < ' a > {
@@ -307,7 +312,11 @@ impl<'a> Reader for BufReader<'a> {
307312
308313impl < ' a > Seek for BufReader < ' a > {
309314 fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
310- fn seek ( & mut self , _pos : i64 , _style : SeekStyle ) -> IoResult < ( ) > { fail ! ( ) }
315+ fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
316+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
317+ self . pos = new as uint ;
318+ Ok ( ( ) )
319+ }
311320}
312321
313322impl < ' a > Buffer for BufReader < ' a > {
@@ -506,4 +515,42 @@ mod test {
506515 Err ( ..) => { }
507516 }
508517 }
518+
519+ #[ test]
520+ fn seek_past_end ( ) {
521+ let buf = [ 0xff ] ;
522+ let mut r = BufReader :: new ( buf) ;
523+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
524+ assert ! ( r. read( & mut [ ] ) . is_err( ) ) ;
525+
526+ let mut r = MemReader :: new ( ~[ 10 ] ) ;
527+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
528+ assert ! ( r. read( & mut [ ] ) . is_err( ) ) ;
529+
530+ let mut r = MemWriter :: new ( ) ;
531+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
532+ assert ! ( r. write( [ 3 ] ) . is_ok( ) ) ;
533+
534+ let mut buf = [ 0 ] ;
535+ let mut r = BufWriter :: new ( buf) ;
536+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
537+ assert ! ( r. write( [ 3 ] ) . is_err( ) ) ;
538+ }
539+
540+ #[ test]
541+ fn seek_before_0 ( ) {
542+ let buf = [ 0xff ] ;
543+ let mut r = BufReader :: new ( buf) ;
544+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
545+
546+ let mut r = MemReader :: new ( ~[ 10 ] ) ;
547+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
548+
549+ let mut r = MemWriter :: new ( ) ;
550+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
551+
552+ let mut buf = [ 0 ] ;
553+ let mut r = BufWriter :: new ( buf) ;
554+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
555+ }
509556}
0 commit comments