diff options
| author | bors <bors@rust-lang.org> | 2017-02-21 16:04:44 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-02-21 16:04:44 +0000 |
| commit | 8a1ce4020c480e455ec902e3616843a3dd5fe489 (patch) | |
| tree | 61f01c0b5cfecf3331188b0301892e313ca6ac51 /src/libstd | |
| parent | 3954c70537cc78dc4a8e28c6ffa0a8ae5198387a (diff) | |
| parent | a2d176e8f4774b84db22540a45eed7b29482f154 (diff) | |
| download | rust-8a1ce4020c480e455ec902e3616843a3dd5fe489.tar.gz rust-8a1ce4020c480e455ec902e3616843a3dd5fe489.zip | |
Auto merge of #39874 - amosonn:master, r=alexcrichton
Fixes overflow in libsdt/io/cursor.rs "seek" Fixes #39631 Test which fails (with old implementation), then fix to implementation.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io/cursor.rs | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 0cff8661d88..60767ea4786 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -200,18 +200,20 @@ impl<T> Cursor<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> { fn seek(&mut self, style: SeekFrom) -> io::Result<u64> { - let pos = match style { - SeekFrom::Start(n) => { self.pos = n; return Ok(n) } - SeekFrom::End(n) => self.inner.as_ref().len() as i64 + n, - SeekFrom::Current(n) => self.pos as i64 + n, + let (base_pos, offset) = match style { + SeekFrom::Start(n) => { self.pos = n; return Ok(n); } + SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), + SeekFrom::Current(n) => (self.pos, n), }; - - if pos < 0 { - Err(Error::new(ErrorKind::InvalidInput, - "invalid seek to a negative position")) + let new_pos = if offset >= 0 { + base_pos.checked_add(offset as u64) } else { - self.pos = pos as u64; - Ok(self.pos) + base_pos.checked_sub((offset.wrapping_neg()) as u64) + }; + match new_pos { + Some(n) => {self.pos = n; Ok(self.pos)} + None => Err(Error::new(ErrorKind::InvalidInput, + "invalid seek to a negative or overflowing position")) } } } @@ -527,6 +529,43 @@ mod tests { } #[test] + fn seek_past_i64() { + let buf = [0xff]; + let mut r = Cursor::new(&buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut buf = [0]; + let mut r = Cursor::new(&mut buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10].into_boxed_slice()); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + } + + #[test] fn seek_before_0() { let buf = [0xff]; let mut r = Cursor::new(&buf[..]); |
