diff --git a/src/read.rs b/src/read.rs index e095a96a..cfe4078b 100644 --- a/src/read.rs +++ b/src/read.rs @@ -263,7 +263,13 @@ impl ZipArchive { ); } - let directory_start = footer.central_directory_offset + archive_offset; + let directory_start = footer + .central_directory_offset + .checked_add(archive_offset) + .ok_or_else(|| { + ZipError::InvalidArchive("Invalid central directory size or offset") + })?; + Ok(( archive_offset, directory_start, @@ -834,6 +840,17 @@ mod test { assert!(reader.is_err()); } + #[test] + fn invalid_offset2() { + use super::ZipArchive; + use std::io; + + let mut v = Vec::new(); + v.extend_from_slice(include_bytes!("../tests/data/invalid_offset2.zip")); + let reader = ZipArchive::new(io::Cursor::new(v)); + assert!(reader.is_err()); + } + #[test] fn zip64_with_leading_junk() { use super::ZipArchive; diff --git a/tests/data/invalid_offset2.zip b/tests/data/invalid_offset2.zip new file mode 100644 index 00000000..944c611d Binary files /dev/null and b/tests/data/invalid_offset2.zip differ