From 42972297f127446587492ee2f883665bec0a14e1 Mon Sep 17 00:00:00 2001 From: Chris Hennick <4961925+Pr0methean@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:18:17 -0700 Subject: [PATCH] fix: Rare bug where find_and_parse would give up prematurely on detecting a false end-of-CDR header --- src/spec.rs | 4 +++- src/write.rs | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/spec.rs b/src/spec.rs index 2bb1489a..b620c01e 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -70,7 +70,9 @@ impl CentralDirectoryEnd { BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64, ))?; let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?; - return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos)); + if let Ok(end_header) = CentralDirectoryEnd::parse(reader) { + return Ok((end_header, cde_start_pos)); + } } pos = match pos.checked_sub(1) { Some(p) => p, diff --git a/src/write.rs b/src/write.rs index 40e664ca..7c5a4f74 100644 --- a/src/write.rs +++ b/src/write.rs @@ -1715,9 +1715,10 @@ mod test { use crate::result::ZipResult; use crate::types::DateTime; use crate::write::SimpleFileOptions; + use crate::CompressionMethod::Stored; use crate::ZipArchive; use std::io; - use std::io::{Read, Write}; + use std::io::{Cursor, Read, Write}; use std::path::PathBuf; #[test] @@ -2199,4 +2200,21 @@ mod test { assert_eq!(file.name(), "sleep"); assert_eq!(file.data_start(), page_size.into()); } + + #[test] + fn test_crash_short_read() { + let mut writer = ZipWriter::new(Cursor::new(Vec::new())); + let comment: Vec = vec![ + 1, 80, 75, 5, 6, 237, 237, 237, 237, 237, 237, 237, 237, 44, 255, 191, 255, 255, 255, + 255, 255, 255, 255, 255, 16, + ]; + writer.set_raw_comment(comment); + let options = SimpleFileOptions::default() + .compression_method(Stored) + .with_alignment(11823); + writer.start_file("", options).unwrap(); + writer.write_all(&[255, 255, 44, 255, 0]).unwrap(); + let written = writer.finish().unwrap(); + let new_writer = ZipWriter::new_append(written).unwrap(); + } }