|
10 | 10 |
|
11 | 11 | use io::prelude::*;
|
12 | 12 |
|
| 13 | +use core::convert::TryInto; |
13 | 14 | use cmp;
|
14 | 15 | use io::{self, SeekFrom, Error, ErrorKind};
|
15 | 16 |
|
@@ -242,26 +243,28 @@ impl<'a> Write for Cursor<&'a mut [u8]> {
|
242 | 243 | #[stable(feature = "rust1", since = "1.0.0")]
|
243 | 244 | impl Write for Cursor<Vec<u8>> {
|
244 | 245 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
| 246 | + let pos: usize = self.position().try_into().map_err(|_| { |
| 247 | + Error::new(ErrorKind::InvalidInput, |
| 248 | + "cursor position exceeds maximum possible vector length") |
| 249 | + })?; |
245 | 250 | // Make sure the internal buffer is as least as big as where we
|
246 | 251 | // currently are
|
247 |
| - let pos = self.position(); |
248 |
| - let amt = pos.saturating_sub(self.inner.len() as u64); |
249 |
| - // use `resize` so that the zero filling is as efficient as possible |
250 | 252 | let len = self.inner.len();
|
251 |
| - self.inner.resize(len + amt as usize, 0); |
252 |
| - |
| 253 | + if len < pos { |
| 254 | + // use `resize` so that the zero filling is as efficient as possible |
| 255 | + self.inner.resize(pos, 0); |
| 256 | + } |
253 | 257 | // Figure out what bytes will be used to overwrite what's currently
|
254 | 258 | // there (left), and what will be appended on the end (right)
|
255 | 259 | {
|
256 |
| - let pos = pos as usize; |
257 | 260 | let space = self.inner.len() - pos;
|
258 | 261 | let (left, right) = buf.split_at(cmp::min(space, buf.len()));
|
259 | 262 | self.inner[pos..pos + left.len()].copy_from_slice(left);
|
260 | 263 | self.inner.extend_from_slice(right);
|
261 | 264 | }
|
262 | 265 |
|
263 | 266 | // Bump us forward
|
264 |
| - self.set_position(pos + buf.len() as u64); |
| 267 | + self.set_position((pos + buf.len()) as u64); |
265 | 268 | Ok(buf.len())
|
266 | 269 | }
|
267 | 270 | fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
@@ -580,4 +583,12 @@ mod tests {
|
580 | 583 | let mut r = Cursor::new(Vec::new());
|
581 | 584 | assert!(r.seek(SeekFrom::End(-2)).is_err());
|
582 | 585 | }
|
| 586 | + |
| 587 | + #[test] |
| 588 | + #[cfg(target_pointer_width = "32")] |
| 589 | + fn vec_seek_and_write_past_usize_max() { |
| 590 | + let mut c = Cursor::new(Vec::new()); |
| 591 | + c.set_position(<usize>::max_value() as u64 + 1); |
| 592 | + assert!(c.write_all(&[1, 2, 3]).is_err()); |
| 593 | + } |
583 | 594 | }
|
0 commit comments