From 8a666b102b0d61b6f76a374f13494c662ae126ef Mon Sep 17 00:00:00 2001 From: Alexander Zaitsev Date: Sat, 22 Jan 2022 17:56:13 +0300 Subject: [PATCH 1/2] fix: add header offset overflow check - during the header offset calculation, perform overflow check Tested: - Local tests --- src/read.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/read.rs b/src/read.rs index 97bccd2d7..7b503ed63 100644 --- a/src/read.rs +++ b/src/read.rs @@ -603,7 +603,10 @@ pub(crate) fn central_header_to_zip_file( } // Account for shifted zip offsets. - result.header_start += archive_offset; + result.header_start = result + .header_start + .checked_add(archive_offset) + .ok_or(ZipError::InvalidArchive("Archive header is too large"))?; Ok(result) } From b053eb0f2cdccbd411d010bf005a7ef18f4de1fd Mon Sep 17 00:00:00 2001 From: Alexander Zaitsev Date: Sat, 22 Jan 2022 19:00:40 +0300 Subject: [PATCH 2/2] feat: add tests - add tests for the large header Tested: - Local run --- tests/issue_234.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/issue_234.rs diff --git a/tests/issue_234.rs b/tests/issue_234.rs new file mode 100644 index 000000000..bd01d1d08 --- /dev/null +++ b/tests/issue_234.rs @@ -0,0 +1,31 @@ +use zip::result::ZipError; + +const BUF: &[u8] = &[ + 0, 80, 75, 1, 2, 127, 120, 0, 3, 3, 75, 80, 232, 3, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 7, 0, 0, 0, + 0, 65, 0, 1, 0, 0, 0, 4, 0, 0, 224, 255, 0, 255, 255, 255, 255, 255, 255, 20, 39, 221, 221, + 221, 221, 221, 221, 205, 221, 221, 221, 42, 221, 221, 221, 221, 221, 221, 221, 221, 38, 34, 34, + 219, 80, 75, 5, 6, 0, 0, 0, 0, 5, 96, 0, 1, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 234, 236, 124, + 221, 221, 37, 221, 221, 221, 221, 221, 129, 4, 0, 0, 221, 221, 80, 75, 1, 2, 127, 120, 0, 4, 0, + 0, 2, 127, 120, 0, 79, 75, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, + 234, 0, 0, 0, 3, 8, 4, 232, 3, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 3, 0, + 221, 209, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 58, 58, 42, 75, 9, 2, 127, + 120, 0, 99, 99, 99, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, 234, 0, 0, 0, 3, 8, + 0, 0, 0, 12, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 58, 58, 58, 42, 175, 221, 253, 221, + 221, 221, 221, 221, 80, 75, 9, 2, 127, 120, 0, 99, 99, 99, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, + 213, 213, 213, 213, 213, 213, 213, 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, 221, 221, + 221, 221, 221, 80, 75, 9, 2, 127, 120, 0, 99, 99, 99, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, +]; + +#[test] +fn invalid_header() { + let reader = std::io::Cursor::new(&BUF); + let archive = zip::ZipArchive::new(reader); + match archive { + Err(ZipError::InvalidArchive(_)) => {} + value => panic!("Unexpected value: {:?}", value), + } +}