diff --git a/src/archive.rs b/src/archive.rs index 8c333322..4a8f3379 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -298,8 +298,10 @@ impl<'a> EntriesFields<'a> { // Store where the next entry is, rounding up by 512 bytes (the size of // a header); - let size = (size + 511) & !(512 - 1); - self.next += size; + let size = size + .checked_add(511) + .ok_or_else(|| other("size overflow"))?; + self.next += size & !(512 - 1); Ok(Some(ret.into_entry())) } diff --git a/tests/all.rs b/tests/all.rs index d29a5190..1fbb770b 100644 --- a/tests/all.rs +++ b/tests/all.rs @@ -1245,3 +1245,16 @@ fn tar_directory_containing_special_files() { t!(ar.append_path("null")); t!(ar.finish()); } + +#[test] +fn header_size_overflow() { + let mut ar = Builder::new(Vec::new()); + let mut header = Header::new_gnu(); + header.set_size(0xffffffffffffffff); + header.set_cksum(); + ar.append(&mut header, "x".as_bytes()).unwrap(); + let result = t!(ar.into_inner()); + let mut ar = Archive::new(&result[..]); + let mut e = ar.entries().unwrap(); + assert!(e.next().unwrap().is_err()); +}