@@ -200,18 +200,20 @@ impl<T> Cursor<T> {
200
200
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
201
201
impl < T > io:: Seek for Cursor < T > where T : AsRef < [ u8 ] > {
202
202
fn seek ( & mut self , style : SeekFrom ) -> io:: Result < u64 > {
203
- let pos = match style {
204
- SeekFrom :: Start ( n) => { self . pos = n; return Ok ( n) }
205
- SeekFrom :: End ( n) => self . inner . as_ref ( ) . len ( ) as i64 + n ,
206
- SeekFrom :: Current ( n) => self . pos as i64 + n ,
203
+ let ( base_pos , offset ) = match style {
204
+ SeekFrom :: Start ( n) => { self . pos = n; return Ok ( n) ; }
205
+ SeekFrom :: End ( n) => ( self . inner . as_ref ( ) . len ( ) as u64 , n ) ,
206
+ SeekFrom :: Current ( n) => ( self . pos , n ) ,
207
207
} ;
208
-
209
- if pos < 0 {
210
- Err ( Error :: new ( ErrorKind :: InvalidInput ,
211
- "invalid seek to a negative position" ) )
208
+ let new_pos = if offset >= 0 {
209
+ base_pos. checked_add ( offset as u64 )
212
210
} else {
213
- self . pos = pos as u64 ;
214
- Ok ( self . pos )
211
+ base_pos. checked_sub ( ( offset. wrapping_neg ( ) ) as u64 )
212
+ } ;
213
+ match new_pos {
214
+ Some ( n) => { self . pos = n; Ok ( self . pos ) }
215
+ None => Err ( Error :: new ( ErrorKind :: InvalidInput ,
216
+ "invalid seek to a negative or overflowing position" ) )
215
217
}
216
218
}
217
219
}
@@ -526,6 +528,43 @@ mod tests {
526
528
assert_eq ! ( r. write( & [ 3 ] ) . unwrap( ) , 0 ) ;
527
529
}
528
530
531
+ #[ test]
532
+ fn seek_past_i64 ( ) {
533
+ let buf = [ 0xff ] ;
534
+ let mut r = Cursor :: new ( & buf[ ..] ) ;
535
+ assert_eq ! ( r. seek( SeekFrom :: Start ( 6 ) ) . unwrap( ) , 6 ) ;
536
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffff0 ) ) . unwrap( ) , 0x7ffffffffffffff6 ) ;
537
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x10 ) ) . unwrap( ) , 0x8000000000000006 ) ;
538
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0 ) ) . unwrap( ) , 0x8000000000000006 ) ;
539
+ assert ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffffd ) ) . is_err( ) ) ;
540
+ assert_eq ! ( r. seek( SeekFrom :: Current ( -0x8000000000000000 ) ) . unwrap( ) , 6 ) ;
541
+
542
+ let mut r = Cursor :: new ( vec ! [ 10 ] ) ;
543
+ assert_eq ! ( r. seek( SeekFrom :: Start ( 6 ) ) . unwrap( ) , 6 ) ;
544
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffff0 ) ) . unwrap( ) , 0x7ffffffffffffff6 ) ;
545
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x10 ) ) . unwrap( ) , 0x8000000000000006 ) ;
546
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0 ) ) . unwrap( ) , 0x8000000000000006 ) ;
547
+ assert ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffffd ) ) . is_err( ) ) ;
548
+ assert_eq ! ( r. seek( SeekFrom :: Current ( -0x8000000000000000 ) ) . unwrap( ) , 6 ) ;
549
+
550
+ let mut buf = [ 0 ] ;
551
+ let mut r = Cursor :: new ( & mut buf[ ..] ) ;
552
+ assert_eq ! ( r. seek( SeekFrom :: Start ( 6 ) ) . unwrap( ) , 6 ) ;
553
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffff0 ) ) . unwrap( ) , 0x7ffffffffffffff6 ) ;
554
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x10 ) ) . unwrap( ) , 0x8000000000000006 ) ;
555
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0 ) ) . unwrap( ) , 0x8000000000000006 ) ;
556
+ assert ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffffd ) ) . is_err( ) ) ;
557
+ assert_eq ! ( r. seek( SeekFrom :: Current ( -0x8000000000000000 ) ) . unwrap( ) , 6 ) ;
558
+
559
+ let mut r = Cursor :: new ( vec ! [ 10 ] . into_boxed_slice ( ) ) ;
560
+ assert_eq ! ( r. seek( SeekFrom :: Start ( 6 ) ) . unwrap( ) , 6 ) ;
561
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffff0 ) ) . unwrap( ) , 0x7ffffffffffffff6 ) ;
562
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0x10 ) ) . unwrap( ) , 0x8000000000000006 ) ;
563
+ assert_eq ! ( r. seek( SeekFrom :: Current ( 0 ) ) . unwrap( ) , 0x8000000000000006 ) ;
564
+ assert ! ( r. seek( SeekFrom :: Current ( 0x7ffffffffffffffd ) ) . is_err( ) ) ;
565
+ assert_eq ! ( r. seek( SeekFrom :: Current ( -0x8000000000000000 ) ) . unwrap( ) , 6 ) ;
566
+ }
567
+
529
568
#[ test]
530
569
fn seek_before_0 ( ) {
531
570
let buf = [ 0xff ] ;
0 commit comments