summaryrefslogtreecommitdiffstats
path: root/third_party/rust/zip/tests
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/zip/tests')
-rw-r--r--third_party/rust/zip/tests/aes_encryption.rs80
-rw-r--r--third_party/rust/zip/tests/data/aes_archive.zipbin0 -> 908 bytes
-rw-r--r--third_party/rust/zip/tests/data/comment_garbage.zipbin0 -> 46 bytes
-rw-r--r--third_party/rust/zip/tests/data/files_and_dirs.zipbin0 -> 462 bytes
-rw-r--r--third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zipbin0 -> 124 bytes
-rw-r--r--third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zipbin0 -> 212 bytes
-rw-r--r--third_party/rust/zip/tests/data/invalid_offset.zipbin0 -> 1241 bytes
-rw-r--r--third_party/rust/zip/tests/data/invalid_offset2.zipbin0 -> 117 bytes
-rw-r--r--third_party/rust/zip/tests/data/mimetype.zipbin0 -> 153 bytes
-rw-r--r--third_party/rust/zip/tests/data/zip64_demo.zipbin0 -> 224 bytes
-rw-r--r--third_party/rust/zip/tests/end_to_end.rs205
-rw-r--r--third_party/rust/zip/tests/invalid_date.rs24
-rw-r--r--third_party/rust/zip/tests/issue_234.rs31
-rw-r--r--third_party/rust/zip/tests/zip64_large.rs211
-rw-r--r--third_party/rust/zip/tests/zip_comment_garbage.rs30
-rw-r--r--third_party/rust/zip/tests/zip_crypto.rs85
16 files changed, 666 insertions, 0 deletions
diff --git a/third_party/rust/zip/tests/aes_encryption.rs b/third_party/rust/zip/tests/aes_encryption.rs
new file mode 100644
index 0000000000..4b393ebf96
--- /dev/null
+++ b/third_party/rust/zip/tests/aes_encryption.rs
@@ -0,0 +1,80 @@
+#![cfg(feature = "aes-crypto")]
+
+use std::io::{self, Read};
+use zip::ZipArchive;
+
+const SECRET_CONTENT: &str = "Lorem ipsum dolor sit amet";
+
+const PASSWORD: &[u8] = b"helloworld";
+
+#[test]
+fn aes256_encrypted_uncompressed_file() {
+ let mut v = Vec::new();
+ v.extend_from_slice(include_bytes!("data/aes_archive.zip"));
+ let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
+
+ let mut file = archive
+ .by_name_decrypt("secret_data_256_uncompressed", PASSWORD)
+ .expect("couldn't find file in archive")
+ .expect("invalid password");
+ assert_eq!("secret_data_256_uncompressed", file.name());
+
+ let mut content = String::new();
+ file.read_to_string(&mut content)
+ .expect("couldn't read encrypted file");
+ assert_eq!(SECRET_CONTENT, content);
+}
+
+#[test]
+fn aes256_encrypted_file() {
+ let mut v = Vec::new();
+ v.extend_from_slice(include_bytes!("data/aes_archive.zip"));
+ let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
+
+ let mut file = archive
+ .by_name_decrypt("secret_data_256", PASSWORD)
+ .expect("couldn't find file in archive")
+ .expect("invalid password");
+ assert_eq!("secret_data_256", file.name());
+
+ let mut content = String::new();
+ file.read_to_string(&mut content)
+ .expect("couldn't read encrypted and compressed file");
+ assert_eq!(SECRET_CONTENT, content);
+}
+
+#[test]
+fn aes192_encrypted_file() {
+ let mut v = Vec::new();
+ v.extend_from_slice(include_bytes!("data/aes_archive.zip"));
+ let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
+
+ let mut file = archive
+ .by_name_decrypt("secret_data_192", PASSWORD)
+ .expect("couldn't find file in archive")
+ .expect("invalid password");
+ assert_eq!("secret_data_192", file.name());
+
+ let mut content = String::new();
+ file.read_to_string(&mut content)
+ .expect("couldn't read encrypted file");
+ assert_eq!(SECRET_CONTENT, content);
+}
+
+#[test]
+fn aes128_encrypted_file() {
+ let mut v = Vec::new();
+ v.extend_from_slice(include_bytes!("data/aes_archive.zip"));
+ let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
+
+ let mut file = archive
+ .by_name_decrypt("secret_data_128", PASSWORD)
+ .expect("couldn't find file in archive")
+ .expect("invalid password");
+ assert_eq!("secret_data_128", file.name());
+
+ let mut content = String::new();
+ file.read_to_string(&mut content)
+ .expect("couldn't read encrypted file");
+ assert_eq!(SECRET_CONTENT, content);
+}
diff --git a/third_party/rust/zip/tests/data/aes_archive.zip b/third_party/rust/zip/tests/data/aes_archive.zip
new file mode 100644
index 0000000000..4cf1fd21ec
--- /dev/null
+++ b/third_party/rust/zip/tests/data/aes_archive.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/comment_garbage.zip b/third_party/rust/zip/tests/data/comment_garbage.zip
new file mode 100644
index 0000000000..f6a289e817
--- /dev/null
+++ b/third_party/rust/zip/tests/data/comment_garbage.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/files_and_dirs.zip b/third_party/rust/zip/tests/data/files_and_dirs.zip
new file mode 100644
index 0000000000..c444078a4a
--- /dev/null
+++ b/third_party/rust/zip/tests/data/files_and_dirs.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip b/third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip
new file mode 100644
index 0000000000..a428ca7e36
--- /dev/null
+++ b/third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip b/third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip
new file mode 100644
index 0000000000..2cc90073f6
--- /dev/null
+++ b/third_party/rust/zip/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/invalid_offset.zip b/third_party/rust/zip/tests/data/invalid_offset.zip
new file mode 100644
index 0000000000..9ff2e07fa8
--- /dev/null
+++ b/third_party/rust/zip/tests/data/invalid_offset.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/invalid_offset2.zip b/third_party/rust/zip/tests/data/invalid_offset2.zip
new file mode 100644
index 0000000000..944c611df1
--- /dev/null
+++ b/third_party/rust/zip/tests/data/invalid_offset2.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/mimetype.zip b/third_party/rust/zip/tests/data/mimetype.zip
new file mode 100644
index 0000000000..2d651cbeb3
--- /dev/null
+++ b/third_party/rust/zip/tests/data/mimetype.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/data/zip64_demo.zip b/third_party/rust/zip/tests/data/zip64_demo.zip
new file mode 100644
index 0000000000..f2ceee303e
--- /dev/null
+++ b/third_party/rust/zip/tests/data/zip64_demo.zip
Binary files differ
diff --git a/third_party/rust/zip/tests/end_to_end.rs b/third_party/rust/zip/tests/end_to_end.rs
new file mode 100644
index 0000000000..09e7ce47e8
--- /dev/null
+++ b/third_party/rust/zip/tests/end_to_end.rs
@@ -0,0 +1,205 @@
+use byteorder::{LittleEndian, WriteBytesExt};
+use std::collections::HashSet;
+use std::io::prelude::*;
+use std::io::{Cursor, Seek};
+use std::iter::FromIterator;
+use zip::write::FileOptions;
+use zip::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};
+
+// This test asserts that after creating a zip file, then reading its contents back out,
+// the extracted data will *always* be exactly the same as the original data.
+#[test]
+fn end_to_end() {
+ for &method in SUPPORTED_COMPRESSION_METHODS {
+ let file = &mut Cursor::new(Vec::new());
+
+ println!("Writing file with {method} compression");
+ write_test_archive(file, method).expect("Couldn't write test zip archive");
+
+ println!("Checking file contents");
+ check_archive_file(file, ENTRY_NAME, Some(method), LOREM_IPSUM);
+ }
+}
+
+// This test asserts that after copying a `ZipFile` to a new `ZipWriter`, then reading its
+// contents back out, the extracted data will *always* be exactly the same as the original data.
+#[test]
+fn copy() {
+ for &method in SUPPORTED_COMPRESSION_METHODS {
+ let src_file = &mut Cursor::new(Vec::new());
+ write_test_archive(src_file, method).expect("Couldn't write to test file");
+
+ let mut tgt_file = &mut Cursor::new(Vec::new());
+
+ {
+ let mut src_archive = zip::ZipArchive::new(src_file).unwrap();
+ let mut zip = zip::ZipWriter::new(&mut tgt_file);
+
+ {
+ let file = src_archive
+ .by_name(ENTRY_NAME)
+ .expect("Missing expected file");
+
+ zip.raw_copy_file(file).expect("Couldn't copy file");
+ }
+
+ {
+ let file = src_archive
+ .by_name(ENTRY_NAME)
+ .expect("Missing expected file");
+
+ zip.raw_copy_file_rename(file, COPY_ENTRY_NAME)
+ .expect("Couldn't copy and rename file");
+ }
+ }
+
+ let mut tgt_archive = zip::ZipArchive::new(tgt_file).unwrap();
+
+ check_archive_file_contents(&mut tgt_archive, ENTRY_NAME, LOREM_IPSUM);
+ check_archive_file_contents(&mut tgt_archive, COPY_ENTRY_NAME, LOREM_IPSUM);
+ }
+}
+
+// This test asserts that after appending to a `ZipWriter`, then reading its contents back out,
+// both the prior data and the appended data will be exactly the same as their originals.
+#[test]
+fn append() {
+ for &method in SUPPORTED_COMPRESSION_METHODS {
+ let mut file = &mut Cursor::new(Vec::new());
+ write_test_archive(file, method).expect("Couldn't write to test file");
+
+ {
+ let mut zip = zip::ZipWriter::new_append(&mut file).unwrap();
+ zip.start_file(
+ COPY_ENTRY_NAME,
+ FileOptions::default().compression_method(method),
+ )
+ .unwrap();
+ zip.write_all(LOREM_IPSUM).unwrap();
+ zip.finish().unwrap();
+ }
+
+ let mut zip = zip::ZipArchive::new(&mut file).unwrap();
+ check_archive_file_contents(&mut zip, ENTRY_NAME, LOREM_IPSUM);
+ check_archive_file_contents(&mut zip, COPY_ENTRY_NAME, LOREM_IPSUM);
+ }
+}
+
+// Write a test zip archive to buffer.
+fn write_test_archive(
+ file: &mut Cursor<Vec<u8>>,
+ method: CompressionMethod,
+) -> zip::result::ZipResult<()> {
+ let mut zip = zip::ZipWriter::new(file);
+
+ zip.add_directory("test/", Default::default())?;
+
+ let options = FileOptions::default()
+ .compression_method(method)
+ .unix_permissions(0o755);
+
+ zip.start_file("test/☃.txt", options)?;
+ zip.write_all(b"Hello, World!\n")?;
+
+ zip.start_file_with_extra_data("test_with_extra_data/🐢.txt", options)?;
+ zip.write_u16::<LittleEndian>(0xbeef)?;
+ zip.write_u16::<LittleEndian>(EXTRA_DATA.len() as u16)?;
+ zip.write_all(EXTRA_DATA)?;
+ zip.end_extra_data()?;
+ zip.write_all(b"Hello, World! Again.\n")?;
+
+ zip.start_file(ENTRY_NAME, options)?;
+ zip.write_all(LOREM_IPSUM)?;
+
+ zip.finish()?;
+ Ok(())
+}
+
+// Load an archive from buffer and check for test data.
+fn check_test_archive<R: Read + Seek>(zip_file: R) -> zip::result::ZipResult<zip::ZipArchive<R>> {
+ let mut archive = zip::ZipArchive::new(zip_file).unwrap();
+
+ // Check archive contains expected file names.
+ {
+ let expected_file_names = [
+ "test/",
+ "test/☃.txt",
+ "test_with_extra_data/🐢.txt",
+ ENTRY_NAME,
+ ];
+ let expected_file_names = HashSet::from_iter(expected_file_names.iter().copied());
+ let file_names = archive.file_names().collect::<HashSet<_>>();
+ assert_eq!(file_names, expected_file_names);
+ }
+
+ // Check an archive file for extra data field contents.
+ {
+ let file_with_extra_data = archive.by_name("test_with_extra_data/🐢.txt")?;
+ let mut extra_data = Vec::new();
+ extra_data.write_u16::<LittleEndian>(0xbeef)?;
+ extra_data.write_u16::<LittleEndian>(EXTRA_DATA.len() as u16)?;
+ extra_data.write_all(EXTRA_DATA)?;
+ assert_eq!(file_with_extra_data.extra_data(), extra_data.as_slice());
+ }
+
+ Ok(archive)
+}
+
+// Read a file in the archive as a string.
+fn read_archive_file<R: Read + Seek>(
+ archive: &mut zip::ZipArchive<R>,
+ name: &str,
+) -> zip::result::ZipResult<String> {
+ let mut file = archive.by_name(name)?;
+
+ let mut contents = String::new();
+ file.read_to_string(&mut contents).unwrap();
+
+ Ok(contents)
+}
+
+// Check a file in the archive contains expected data and properties.
+fn check_archive_file(
+ zip_file: &mut Cursor<Vec<u8>>,
+ name: &str,
+ expected_method: Option<CompressionMethod>,
+ expected_data: &[u8],
+) {
+ let mut archive = check_test_archive(zip_file).unwrap();
+
+ if let Some(expected_method) = expected_method {
+ // Check the file's compression method.
+ let file = archive.by_name(name).unwrap();
+ let real_method = file.compression();
+
+ assert_eq!(
+ expected_method, real_method,
+ "File does not have expected compression method"
+ );
+ }
+
+ check_archive_file_contents(&mut archive, name, expected_data);
+}
+
+// Check a file in the archive contains the given data.
+fn check_archive_file_contents<R: Read + Seek>(
+ archive: &mut zip::ZipArchive<R>,
+ name: &str,
+ expected: &[u8],
+) {
+ let file_contents: String = read_archive_file(archive, name).unwrap();
+ assert_eq!(file_contents.as_bytes(), expected);
+}
+
+const LOREM_IPSUM : &[u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tellus elit, tristique vitae mattis egestas, ultricies vitae risus. Quisque sit amet quam ut urna aliquet
+molestie. Proin blandit ornare dui, a tempor nisl accumsan in. Praesent a consequat felis. Morbi metus diam, auctor in auctor vel, feugiat id odio. Curabitur ex ex,
+dictum quis auctor quis, suscipit id lorem. Aliquam vestibulum dolor nec enim vehicula, porta tristique augue tincidunt. Vivamus ut gravida est. Sed pellentesque, dolor
+vitae tristique consectetur, neque lectus pulvinar dui, sed feugiat purus diam id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
+inceptos himenaeos. Maecenas feugiat velit in ex ultrices scelerisque id id neque.
+";
+
+const EXTRA_DATA: &[u8] = b"Extra Data";
+
+const ENTRY_NAME: &str = "test/lorem_ipsum.txt";
+
+const COPY_ENTRY_NAME: &str = "test/lorem_ipsum_renamed.txt";
diff --git a/third_party/rust/zip/tests/invalid_date.rs b/third_party/rust/zip/tests/invalid_date.rs
new file mode 100644
index 0000000000..3f24e2514d
--- /dev/null
+++ b/third_party/rust/zip/tests/invalid_date.rs
@@ -0,0 +1,24 @@
+use std::io::Cursor;
+use zip::read::ZipArchive;
+
+const BUF: &[u8] = &[
+ 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x69, 0x6e,
+ 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f,
+ 0x55, 0x54, 0x09, 0x00, 0x03, 0xf4, 0x5c, 0x88, 0x5a, 0xf4, 0x5c, 0x88, 0x5a, 0x75, 0x78, 0x0b,
+ 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02,
+ 0x1e, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, // time part: 0 seconds, 0 minutes, 0 hours
+ 0x00, 0x00, // date part: day 0 (invalid), month 0 (invalid), year 0 (1980)
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x18, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xed, 0x41, 0x00, 0x00, 0x00, 0x00, 0x69, 0x6e,
+ 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f,
+ 0x55, 0x54, 0x05, 0x00, 0x03, 0xf4, 0x5c, 0x88, 0x5a, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8,
+ 0x03, 0x00, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00,
+];
+
+#[test]
+fn invalid_date() {
+ let _archive = ZipArchive::new(Cursor::new(BUF)).unwrap();
+}
diff --git a/third_party/rust/zip/tests/issue_234.rs b/third_party/rust/zip/tests/issue_234.rs
new file mode 100644
index 0000000000..bd01d1d08a
--- /dev/null
+++ b/third_party/rust/zip/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),
+ }
+}
diff --git a/third_party/rust/zip/tests/zip64_large.rs b/third_party/rust/zip/tests/zip64_large.rs
new file mode 100644
index 0000000000..468ef198f6
--- /dev/null
+++ b/third_party/rust/zip/tests/zip64_large.rs
@@ -0,0 +1,211 @@
+// The following is a hexdump of a zip64 file containing the following files:
+// zero4400: 4400 MB of zeroes
+// zero100: 100 MB of zeroes
+// zero4400_2: 4400 MB of zeroes
+//
+// 00000000 50 4b 03 04 2d 00 00 00 00 00 1b 6e 51 4d 66 82 |PK..-......nQMf.|
+// 00000010 13 da ff ff ff ff ff ff ff ff 08 00 30 00 7a 65 |............0.ze|
+// 00000020 72 6f 34 34 30 30 55 54 09 00 03 a5 21 c7 5b db |ro4400UT....!.[.|
+// 00000030 21 c7 5b 75 78 0b 00 01 04 e8 03 00 00 04 e8 03 |!.[ux...........|
+// 00000040 00 00 01 00 10 00 00 00 00 13 01 00 00 00 00 00 |................|
+// 00000050 00 13 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+// 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+// *
+// 113000050 00 00 00 00 00 00 50 4b 03 04 0a 00 00 00 00 00 |......PK........|
+// 113000060 2b 6e 51 4d 98 23 28 4b 00 00 40 06 00 00 40 06 |+nQM.#(K..@...@.|
+// 113000070 07 00 1c 00 7a 65 72 6f 31 30 30 55 54 09 00 03 |....zero100UT...|
+// 113000080 c2 21 c7 5b c2 21 c7 5b 75 78 0b 00 01 04 e8 03 |.!.[.!.[ux......|
+// 113000090 00 00 04 e8 03 00 00 00 00 00 00 00 00 00 00 00 |................|
+// 1130000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+// *
+// 119400090 00 00 00 00 00 00 00 50 4b 03 04 2d 00 00 00 00 |.......PK..-....|
+// 1194000a0 00 3b 6e 51 4d 66 82 13 da ff ff ff ff ff ff ff |.;nQMf..........|
+// 1194000b0 ff 0a 00 30 00 7a 65 72 6f 34 34 30 30 5f 32 55 |...0.zero4400_2U|
+// 1194000c0 54 09 00 03 e2 21 c7 5b db 21 c7 5b 75 78 0b 00 |T....!.[.!.[ux..|
+// 1194000d0 01 04 e8 03 00 00 04 e8 03 00 00 01 00 10 00 00 |................|
+// 1194000e0 00 00 13 01 00 00 00 00 00 00 13 01 00 00 00 00 |................|
+// 1194000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+// *
+// 22c4000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 |...............P|
+// 22c4000f0 4b 01 02 1e 03 2d 00 00 00 00 00 1b 6e 51 4d 66 |K....-......nQMf|
+// 22c400100 82 13 da ff ff ff ff ff ff ff ff 08 00 2c 00 00 |.............,..|
+// 22c400110 00 00 00 00 00 00 00 a4 81 00 00 00 00 7a 65 72 |.............zer|
+// 22c400120 6f 34 34 30 30 55 54 05 00 03 a5 21 c7 5b 75 78 |o4400UT....!.[ux|
+// 22c400130 0b 00 01 04 e8 03 00 00 04 e8 03 00 00 01 00 10 |................|
+// 22c400140 00 00 00 00 13 01 00 00 00 00 00 00 13 01 00 00 |................|
+// 22c400150 00 50 4b 01 02 1e 03 0a 00 00 00 00 00 2b 6e 51 |.PK..........+nQ|
+// 22c400160 4d 98 23 28 4b 00 00 40 06 00 00 40 06 07 00 24 |M.#(K..@...@...$|
+// 22c400170 00 00 00 00 00 00 00 00 00 a4 81 ff ff ff ff 7a |...............z|
+// 22c400180 65 72 6f 31 30 30 55 54 05 00 03 c2 21 c7 5b 75 |ero100UT....!.[u|
+// 22c400190 78 0b 00 01 04 e8 03 00 00 04 e8 03 00 00 01 00 |x...............|
+// 22c4001a0 08 00 56 00 00 13 01 00 00 00 50 4b 01 02 1e 03 |..V.......PK....|
+// 22c4001b0 2d 00 00 00 00 00 3b 6e 51 4d 66 82 13 da ff ff |-.....;nQMf.....|
+// 22c4001c0 ff ff ff ff ff ff 0a 00 34 00 00 00 00 00 00 00 |........4.......|
+// 22c4001d0 00 00 a4 81 ff ff ff ff 7a 65 72 6f 34 34 30 30 |........zero4400|
+// 22c4001e0 5f 32 55 54 05 00 03 e2 21 c7 5b 75 78 0b 00 01 |_2UT....!.[ux...|
+// 22c4001f0 04 e8 03 00 00 04 e8 03 00 00 01 00 18 00 00 00 |................|
+// 22c400200 00 13 01 00 00 00 00 00 00 13 01 00 00 00 97 00 |................|
+// 22c400210 40 19 01 00 00 00 50 4b 06 06 2c 00 00 00 00 00 |@.....PK..,.....|
+// 22c400220 00 00 1e 03 2d 00 00 00 00 00 00 00 00 00 03 00 |....-...........|
+// 22c400230 00 00 00 00 00 00 03 00 00 00 00 00 00 00 27 01 |..............'.|
+// 22c400240 00 00 00 00 00 00 ef 00 40 2c 02 00 00 00 50 4b |........@,....PK|
+// 22c400250 06 07 00 00 00 00 16 02 40 2c 02 00 00 00 01 00 |........@,......|
+// 22c400260 00 00 50 4b 05 06 00 00 00 00 03 00 03 00 27 01 |..PK..........'.|
+// 22c400270 00 00 ff ff ff ff 00 00 |........|
+// 22c400278
+use std::io::{self, Read, Seek, SeekFrom};
+
+const BLOCK1_LENGTH: u64 = 0x60;
+const BLOCK1: [u8; BLOCK1_LENGTH as usize] = [
+ 0x50, 0x4b, 0x03, 0x04, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x6e, 0x51, 0x4d, 0x66, 0x82,
+ 0x13, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x30, 0x00, 0x7a, 0x65,
+ 0x72, 0x6f, 0x34, 0x34, 0x30, 0x30, 0x55, 0x54, 0x09, 0x00, 0x03, 0xa5, 0x21, 0xc7, 0x5b, 0xdb,
+ 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03,
+ 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+];
+
+const BLOCK2_LENGTH: u64 = 0x50;
+const BLOCK2: [u8; BLOCK2_LENGTH as usize] = [
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2b, 0x6e, 0x51, 0x4d, 0x98, 0x23, 0x28, 0x4b, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x06,
+ 0x07, 0x00, 0x1c, 0x00, 0x7a, 0x65, 0x72, 0x6f, 0x31, 0x30, 0x30, 0x55, 0x54, 0x09, 0x00, 0x03,
+ 0xc2, 0x21, 0xc7, 0x5b, 0xc2, 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03,
+ 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+];
+
+const BLOCK3_LENGTH: u64 = 0x60;
+const BLOCK3: [u8; BLOCK3_LENGTH as usize] = [
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x2d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3b, 0x6e, 0x51, 0x4d, 0x66, 0x82, 0x13, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x0a, 0x00, 0x30, 0x00, 0x7a, 0x65, 0x72, 0x6f, 0x34, 0x34, 0x30, 0x30, 0x5f, 0x32, 0x55,
+ 0x54, 0x09, 0x00, 0x03, 0xe2, 0x21, 0xc7, 0x5b, 0xdb, 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00,
+ 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00,
+];
+
+const BLOCK4_LENGTH: u64 = 0x198;
+const BLOCK4: [u8; BLOCK4_LENGTH as usize] = [
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x4b, 0x01, 0x02, 0x1e, 0x03, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x6e, 0x51, 0x4d, 0x66,
+ 0x82, 0x13, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x2c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x65, 0x72,
+ 0x6f, 0x34, 0x34, 0x30, 0x30, 0x55, 0x54, 0x05, 0x00, 0x03, 0xa5, 0x21, 0xc7, 0x5b, 0x75, 0x78,
+ 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00,
+ 0x00, 0x50, 0x4b, 0x01, 0x02, 0x1e, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6e, 0x51,
+ 0x4d, 0x98, 0x23, 0x28, 0x4b, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x06, 0x07, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0xff, 0xff, 0xff, 0xff, 0x7a,
+ 0x65, 0x72, 0x6f, 0x31, 0x30, 0x30, 0x55, 0x54, 0x05, 0x00, 0x03, 0xc2, 0x21, 0xc7, 0x5b, 0x75,
+ 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00,
+ 0x08, 0x00, 0x56, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x1e, 0x03,
+ 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6e, 0x51, 0x4d, 0x66, 0x82, 0x13, 0xda, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xa4, 0x81, 0xff, 0xff, 0xff, 0xff, 0x7a, 0x65, 0x72, 0x6f, 0x34, 0x34, 0x30, 0x30,
+ 0x5f, 0x32, 0x55, 0x54, 0x05, 0x00, 0x03, 0xe2, 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00, 0x01,
+ 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x97, 0x00,
+ 0x40, 0x19, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x06, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x03, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x40, 0x2c, 0x02, 0x00, 0x00, 0x00, 0x50, 0x4b,
+ 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x40, 0x2c, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x27, 0x01,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+];
+
+const BLOCK1_START: u64 = 0x000000000;
+const BLOCK2_START: u64 = 0x113000050;
+const BLOCK3_START: u64 = 0x119400090;
+const BLOCK4_START: u64 = 0x22c4000e0;
+
+const BLOCK1_END: u64 = BLOCK1_START + BLOCK1_LENGTH - 1;
+const BLOCK2_END: u64 = BLOCK2_START + BLOCK2_LENGTH - 1;
+const BLOCK3_END: u64 = BLOCK3_START + BLOCK3_LENGTH - 1;
+const BLOCK4_END: u64 = BLOCK4_START + BLOCK4_LENGTH - 1;
+
+const TOTAL_LENGTH: u64 = BLOCK4_START + BLOCK4_LENGTH;
+
+struct Zip64File {
+ pointer: u64,
+}
+
+impl Zip64File {
+ fn new() -> Self {
+ Zip64File { pointer: 0 }
+ }
+}
+
+impl Seek for Zip64File {
+ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+ match pos {
+ SeekFrom::Start(offset) => {
+ self.pointer = offset;
+ }
+ SeekFrom::End(offset) => {
+ if offset > 0 || offset < -(TOTAL_LENGTH as i64) {
+ return Err(io::Error::new(io::ErrorKind::Other, "Invalid seek offset"));
+ }
+ self.pointer = (TOTAL_LENGTH as i64 + offset) as u64;
+ }
+ SeekFrom::Current(offset) => {
+ let seekpos = self.pointer as i64 + offset;
+ if seekpos < 0 || seekpos as u64 > TOTAL_LENGTH {
+ return Err(io::Error::new(io::ErrorKind::Other, "Invalid seek offset"));
+ }
+ self.pointer = seekpos as u64;
+ }
+ }
+ Ok(self.pointer)
+ }
+}
+
+impl Read for Zip64File {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ if self.pointer >= TOTAL_LENGTH {
+ return Ok(0);
+ }
+ match self.pointer {
+ BLOCK1_START..=BLOCK1_END => {
+ buf[0] = BLOCK1[(self.pointer - BLOCK1_START) as usize];
+ }
+ BLOCK2_START..=BLOCK2_END => {
+ buf[0] = BLOCK2[(self.pointer - BLOCK2_START) as usize];
+ }
+ BLOCK3_START..=BLOCK3_END => {
+ buf[0] = BLOCK3[(self.pointer - BLOCK3_START) as usize];
+ }
+ BLOCK4_START..=BLOCK4_END => {
+ buf[0] = BLOCK4[(self.pointer - BLOCK4_START) as usize];
+ }
+ _ => {
+ buf[0] = 0;
+ }
+ }
+ self.pointer += 1;
+ Ok(1)
+ }
+}
+
+#[test]
+fn zip64_large() {
+ let zipfile = Zip64File::new();
+ let mut archive = zip::ZipArchive::new(zipfile).unwrap();
+ let mut buf = [0u8; 32];
+
+ for i in 0..archive.len() {
+ let mut file = archive.by_index(i).unwrap();
+ let outpath = file.enclosed_name().unwrap();
+ println!(
+ "Entry {} has name \"{}\" ({} bytes)",
+ i,
+ outpath.display(),
+ file.size()
+ );
+
+ match file.read_exact(&mut buf) {
+ Ok(()) => println!("The first {} bytes are: {:?}", buf.len(), buf),
+ Err(e) => println!("Could not read the file: {e:?}"),
+ };
+ }
+}
diff --git a/third_party/rust/zip/tests/zip_comment_garbage.rs b/third_party/rust/zip/tests/zip_comment_garbage.rs
new file mode 100644
index 0000000000..ef4d975079
--- /dev/null
+++ b/third_party/rust/zip/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());
+}
diff --git a/third_party/rust/zip/tests/zip_crypto.rs b/third_party/rust/zip/tests/zip_crypto.rs
new file mode 100644
index 0000000000..6c4d6b811c
--- /dev/null
+++ b/third_party/rust/zip/tests/zip_crypto.rs
@@ -0,0 +1,85 @@
+// The following is a hexdump of a zip file containing the following
+// ZipCrypto encrypted file:
+// test.txt: 35 bytes, contents: `abcdefghijklmnopqrstuvwxyz123456789`, password: `test`
+//
+// 00000000 50 4b 03 04 14 00 01 00 00 00 54 bd b5 50 2f 20 |PK........T..P/ |
+// 00000010 79 55 2f 00 00 00 23 00 00 00 08 00 00 00 74 65 |yU/...#.......te|
+// 00000020 73 74 2e 74 78 74 ca 2d 1d 27 19 19 63 43 77 9a |st.txt.-.'..cCw.|
+// 00000030 71 76 c9 ec d1 6f d9 f5 22 67 b3 8f 52 b5 41 bc |qv...o.."g..R.A.|
+// 00000040 5c 36 f2 1d 84 c3 c0 28 3b fd e1 70 c2 cc 0c 11 |\6.....(;..p....|
+// 00000050 0c c5 95 2f a4 50 4b 01 02 3f 00 14 00 01 00 00 |.../.PK..?......|
+// 00000060 00 54 bd b5 50 2f 20 79 55 2f 00 00 00 23 00 00 |.T..P/ yU/...#..|
+// 00000070 00 08 00 24 00 00 00 00 00 00 00 20 00 00 00 00 |...$....... ....|
+// 00000080 00 00 00 74 65 73 74 2e 74 78 74 0a 00 20 00 00 |...test.txt.. ..|
+// 00000090 00 00 00 01 00 18 00 31 b2 3b bf b8 2f d6 01 31 |.......1.;../..1|
+// 000000a0 b2 3b bf b8 2f d6 01 a8 c4 45 bd b8 2f d6 01 50 |.;../....E../..P|
+// 000000b0 4b 05 06 00 00 00 00 01 00 01 00 5a 00 00 00 55 |K..........Z...U|
+// 000000c0 00 00 00 00 00 |.....|
+// 000000c5
+
+use std::io::Cursor;
+use std::io::Read;
+
+#[test]
+fn encrypted_file() {
+ let zip_file_bytes = &mut Cursor::new(vec![
+ 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0xbd, 0xb5, 0x50, 0x2f,
+ 0x20, 0x79, 0x55, 0x2f, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, 0x74, 0xca, 0x2d, 0x1d, 0x27, 0x19, 0x19, 0x63,
+ 0x43, 0x77, 0x9a, 0x71, 0x76, 0xc9, 0xec, 0xd1, 0x6f, 0xd9, 0xf5, 0x22, 0x67, 0xb3, 0x8f,
+ 0x52, 0xb5, 0x41, 0xbc, 0x5c, 0x36, 0xf2, 0x1d, 0x84, 0xc3, 0xc0, 0x28, 0x3b, 0xfd, 0xe1,
+ 0x70, 0xc2, 0xcc, 0x0c, 0x11, 0x0c, 0xc5, 0x95, 0x2f, 0xa4, 0x50, 0x4b, 0x01, 0x02, 0x3f,
+ 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0xbd, 0xb5, 0x50, 0x2f, 0x20, 0x79, 0x55,
+ 0x2f, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
+ 0x2e, 0x74, 0x78, 0x74, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18,
+ 0x00, 0x31, 0xb2, 0x3b, 0xbf, 0xb8, 0x2f, 0xd6, 0x01, 0x31, 0xb2, 0x3b, 0xbf, 0xb8, 0x2f,
+ 0xd6, 0x01, 0xa8, 0xc4, 0x45, 0xbd, 0xb8, 0x2f, 0xd6, 0x01, 0x50, 0x4b, 0x05, 0x06, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ ]);
+
+ let mut archive = zip::ZipArchive::new(zip_file_bytes).unwrap();
+
+ assert_eq!(archive.len(), 1); //Only one file inside archive: `test.txt`
+
+ {
+ // No password
+ let file = archive.by_index(0);
+ match file {
+ Err(zip::result::ZipError::UnsupportedArchive(
+ zip::result::ZipError::PASSWORD_REQUIRED,
+ )) => (),
+ Err(_) => panic!(
+ "Expected PasswordRequired error when opening encrypted file without password"
+ ),
+ Ok(_) => panic!("Error: Successfully opened encrypted file without password?!"),
+ }
+ }
+
+ {
+ // Wrong password
+ let file = archive.by_index_decrypt(0, b"wrong password");
+ match file {
+ Ok(Err(zip::result::InvalidPassword)) => (),
+ Err(_) => panic!(
+ "Expected InvalidPassword error when opening encrypted file with wrong password"
+ ),
+ Ok(Ok(_)) => panic!("Error: Successfully opened encrypted file with wrong password?!"),
+ }
+ }
+
+ {
+ // Correct password, read contents
+ let mut file = archive
+ .by_index_decrypt(0, "test".as_bytes())
+ .unwrap()
+ .unwrap();
+ let file_name = file.enclosed_name().unwrap();
+ assert_eq!(file_name, std::path::PathBuf::from("test.txt"));
+
+ let mut data = Vec::new();
+ file.read_to_end(&mut data).unwrap();
+ assert_eq!(data, "abcdefghijklmnopqrstuvwxyz123456789".as_bytes());
+ }
+}