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.
This commit is contained in:
commit
8a1ce4020c
|
@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -526,6 +528,43 @@ mod tests {
|
|||
assert_eq!(r.write(&[3]).unwrap(), 0);
|
||||
}
|
||||
|
||||
#[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];
|
||||
|
|
Loading…
Reference in New Issue