From 5c4f0906f8dd99e1924bd21d0029d1c2a1eec3e3 Mon Sep 17 00:00:00 2001 From: Davide Romanini Date: Sun, 19 Apr 2020 20:33:14 +0200 Subject: [PATCH 1/3] allow for garbage after comment data --- src/spec.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/spec.rs b/src/spec.rs index 8fa8c5c1c..63d4d2874 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -66,11 +66,9 @@ impl CentralDirectoryEnd { reader.seek(io::SeekFrom::Current( BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64, ))?; - let comment_length = reader.read_u16::()? as u64; - if file_length - pos - HEADER_SIZE == comment_length { - let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?; - return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos)); - } + + let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?; + return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos)); } pos = match pos.checked_sub(1) { Some(p) => p, From b91f48a2242c270d1d80c6338cdca039dcc5b545 Mon Sep 17 00:00:00 2001 From: Davide Romanini Date: Thu, 13 Aug 2020 15:53:38 +0200 Subject: [PATCH 2/3] fix fmt --- src/spec.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/spec.rs b/src/spec.rs index 63d4d2874..91966b67f 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -66,7 +66,6 @@ impl CentralDirectoryEnd { reader.seek(io::SeekFrom::Current( BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64, ))?; - let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?; return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos)); } From 5eefdf8271e5cfccbe01b84721b699742318c7c8 Mon Sep 17 00:00:00 2001 From: Davide Romanini Date: Wed, 19 Aug 2020 18:53:58 +0200 Subject: [PATCH 3/3] add test for handling comment garbage --- tests/data/comment_garbage.zip | Bin 0 -> 46 bytes tests/zip_comment_garbage.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/data/comment_garbage.zip create mode 100644 tests/zip_comment_garbage.rs diff --git a/tests/data/comment_garbage.zip b/tests/data/comment_garbage.zip new file mode 100644 index 0000000000000000000000000000000000000000..f6a289e817b4686757c5c421b2e7958aa08b1068 GIT binary patch literal 46 hcmWIWW@TeQ18fY%8TmyedilAzsd*&|NjZry3;>a|35Wmy literal 0 HcmV?d00001 diff --git a/tests/zip_comment_garbage.rs b/tests/zip_comment_garbage.rs new file mode 100644 index 000000000..ef4d97507 --- /dev/null +++ b/tests/zip_comment_garbage.rs @@ -0,0 +1,30 @@ +// Some zip files can contain garbage after the comment. For example, python zipfile generates +// it when opening a zip in 'a' mode: +// +// >>> from zipfile import ZipFile +// >>> with ZipFile('comment_garbage.zip', 'a') as z: +// ... z.comment = b'long comment bla bla bla' +// ... +// >>> with ZipFile('comment_garbage.zip', 'a') as z: +// ... z.comment = b'short.' +// ... +// >>> +// +// Hexdump: +// +// 00000000 50 4b 05 06 00 00 00 00 00 00 00 00 00 00 00 00 |PK..............| +// 00000010 00 00 00 00 06 00 73 68 6f 72 74 2e 6f 6d 6d 65 |......short.omme| +// 00000020 6e 74 20 62 6c 61 20 62 6c 61 20 62 6c 61 |nt bla bla bla| +// 0000002e + +use std::io; +use zip::ZipArchive; + +#[test] +fn correctly_handle_zip_with_garbage_after_comment() { + let mut v = Vec::new(); + v.extend_from_slice(include_bytes!("../tests/data/comment_garbage.zip")); + let archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file"); + + assert_eq!(archive.comment(), "short.".as_bytes()); +}