Skip to content

Commit 56c5934

Browse files
authored
Fix integer overflows and truncation (#278)
Signed-off-by: Tobias Stoeckmann <[email protected]>
1 parent 5a949d6 commit 56c5934

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

src/spooled.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl SpooledTempFile {
9696
}
9797

9898
pub fn set_len(&mut self, size: u64) -> Result<(), io::Error> {
99-
if size as usize > self.max_size {
99+
if size > self.max_size as u64 {
100100
self.roll()?; // does nothing if already rolled over
101101
}
102102
match &mut self.inner {
@@ -157,7 +157,7 @@ impl Write for SpooledTempFile {
157157
// roll over to file if necessary
158158
if matches! {
159159
&self.inner, SpooledData::InMemory(cursor)
160-
if cursor.position() as usize + buf.len() > self.max_size
160+
if cursor.position().saturating_add(buf.len() as u64) > self.max_size as u64
161161
} {
162162
self.roll()?;
163163
}
@@ -173,8 +173,10 @@ impl Write for SpooledTempFile {
173173
if matches! {
174174
&self.inner, SpooledData::InMemory(cursor)
175175
// Borrowed from the rust standard library.
176-
if cursor.position() as usize + bufs.iter()
177-
.fold(0usize, |a, b| a.saturating_add(b.len())) > self.max_size
176+
if bufs
177+
.iter()
178+
.fold(cursor.position(), |a, b| a.saturating_add(b.len() as u64))
179+
> self.max_size as u64
178180
} {
179181
self.roll()?;
180182
}

src/util.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ use std::{io, iter::repeat_with};
55
use crate::error::IoResultExt;
66

77
fn tmpname(prefix: &OsStr, suffix: &OsStr, rand_len: usize) -> OsString {
8-
let mut buf = OsString::with_capacity(prefix.len() + suffix.len() + rand_len);
8+
let capacity = prefix
9+
.len()
10+
.saturating_add(suffix.len())
11+
.saturating_add(rand_len);
12+
let mut buf = OsString::with_capacity(capacity);
913
buf.push(prefix);
1014
let mut char_buf = [0u8; 4];
1115
for c in repeat_with(fastrand::alphanumeric).take(rand_len) {

tests/spooled.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,18 @@ fn test_set_len_rollover() {
305305
assert_eq!(t.read_to_end(&mut buf).unwrap(), 20);
306306
assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
307307
}
308+
309+
#[test]
310+
fn test_write_overflow() {
311+
let mut t = spooled_tempfile(10);
312+
t.seek(SeekFrom::Start(u64::MAX)).unwrap();
313+
assert!(t.write(b"abcde").is_err());
314+
}
315+
316+
#[cfg(target_pointer_width = "32")]
317+
#[test]
318+
fn test_set_len_truncation() {
319+
let mut t = spooled_tempfile(100);
320+
assert!(t.set_len(usize::MAX as u64 + 5).is_ok());
321+
assert!(t.is_rolled());
322+
}

0 commit comments

Comments
 (0)