summaryrefslogtreecommitdiffstats
path: root/vendor/zip
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:24 +0000
commit023939b627b7dc93b01471f7d41fb8553ddb4ffa (patch)
tree60fc59477c605c72b0a1051409062ddecc43f877 /vendor/zip
parentAdding debian version 1.72.1+dfsg1-1. (diff)
downloadrustc-023939b627b7dc93b01471f7d41fb8553ddb4ffa.tar.xz
rustc-023939b627b7dc93b01471f7d41fb8553ddb4ffa.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/zip')
-rw-r--r--vendor/zip/.cargo-checksum.json2
-rw-r--r--vendor/zip/CHANGELOG.md10
-rw-r--r--vendor/zip/Cargo.lock110
-rw-r--r--vendor/zip/Cargo.toml7
-rw-r--r--vendor/zip/README.md7
-rw-r--r--vendor/zip/src/aes_ctr.rs11
-rw-r--r--vendor/zip/src/lib.rs11
-rw-r--r--vendor/zip/src/read.rs64
-rw-r--r--vendor/zip/src/read/stream.rs372
-rw-r--r--vendor/zip/src/types.rs72
-rw-r--r--vendor/zip/src/unstable.rs20
-rw-r--r--vendor/zip/src/write.rs67
-rw-r--r--vendor/zip/src/zipcrypto.rs46
-rw-r--r--vendor/zip/tests/issue_234.rs2
-rw-r--r--vendor/zip/tests/zip_crypto.rs17
15 files changed, 657 insertions, 161 deletions
diff --git a/vendor/zip/.cargo-checksum.json b/vendor/zip/.cargo-checksum.json
index 9766507eb..be96805bf 100644
--- a/vendor/zip/.cargo-checksum.json
+++ b/vendor/zip/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"da022ffbfcbf04616fc8e31b7a38fd7c8f2ad47a7fb42750fc04de110cf95857","CODE_OF_CONDUCT.md":"77930b2129928632cae79e10d0863885b34729e4f144f3ae5443cff65997196a","Cargo.lock":"5c81aacae00a3838358fed3e453cbb128f9870162a280d91b77f20c7b4c94390","Cargo.toml":"69d71445861d823f30fbd330f74cb395ed1f4e981f3c61e4754eda2f1f1cb0b4","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"4da0a964d8fb78a5caae4674b4f69fc24f080167af56927d1a5c15412f9f672d","benches/read_entry.rs":"700235ee560887f33da56895d2a4da901c070b2a6a59aef90331046af4ddadad","benches/read_metadata.rs":"591e5adb9d36bf66da21d7e0d36a129c9bcf1331fa11714df8c53c860aee65ff","examples/extract.rs":"81f58da293553fe019319348e1d226a2d192480667877e72d77ab58812f5de1b","examples/extract_lorem.rs":"2d438706ca6e02468f362a54f4f2125598d2be1051e7ce40b71be58cfd703669","examples/file_info.rs":"20639234293511022938c8204488d182ccbcdfb59d962000acd8ac8f2f6db667","examples/stdin_info.rs":"5735801c9692a9b6ec35da6e6a65807db48b577068ab9df0018343df5161034b","examples/write_dir.rs":"224239e040c583f2e1ca4b1328ebe1a63b3c2213df6da8232cd62e004db05587","examples/write_sample.rs":"f723bf69676492599c2684aa995177f80e2aa922f1c9ae1681ed39e0a15959ad","src/aes.rs":"c1b19bdf15c75cc27b5657d1dc574b5c5ebcdc7ca2573e9909cc6ba1ffe7f6d8","src/aes_ctr.rs":"6a7a07c9538daf53624818f82084c6655db3862ca00751f3679c8b0bc346b70d","src/compression.rs":"84f8ded41182155cfbdb1ce79b9dc84cae0a6e55557021cf9f2d7168d8913b48","src/cp437.rs":"e3a044ddefc947f6d9c26ba50ebd438955d90b8971ad8b15e5dd1194495f3b93","src/crc32.rs":"6c5a48834dfa1ab33590fcc63f4121ee6d3f8fbcc5018e905c4d8570096874cf","src/lib.rs":"7c2f6bc3dde9575eeeaef9569139f28351333c29362f74569e627ad7be5a10b2","src/read.rs":"1c8e60c37a7016399d5bdf3796bcd4ad8a5cdf7450498233c7d056fd7533692a","src/result.rs":"7dc62da507ef2228313ed617d01f4d207eacb0b66352a497d24f04298e90e5df","src/spec.rs":"2a249aeb3c58ca475b5c7da6919cb61ac3cbe07b94a0cb3c730646d46fb265a8","src/types.rs":"21a37a8632bd9b2572a7ccd19e6048dcc453a3c4fd7583f3eddefbec7dd641a5","src/write.rs":"16ccc971f2858042d2f92e0448a72849745ea0a25449fd7c8961b78a466b6e6e","src/zipcrypto.rs":"4fe362af2a8e419d9cff6acc165acdc0dccaacc53baec7269b5f55dfcd396f5c","tests/aes_encryption.rs":"3733df1f5dcab4e9f9b9ec25cc7660f23c917759670e9b2e6fe77cfcd771faa9","tests/data/aes_archive.zip":"4abb3f304d1ab669453b7c4eae80db6ce8aff4ab91c8ab9a6edf90bbfede12f4","tests/data/comment_garbage.zip":"4a908af18691e50fc7773b34669a8ab6cb60875bee4d60fb7cd66d90eed55d2b","tests/data/files_and_dirs.zip":"e54cd8d084739f8d0b119d769c1263507b4da915cc38e4e2d3e4ef17c718f317","tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip":"c680ed5ad622aae23eea3b5d90145cb79550e413cc6e9a7b67bb1043851512ee","tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip":"7c272255e825aff7167dc8d1f2e1d16583e58347bb56ecf9879bdb07c6ad18e9","tests/data/invalid_offset.zip":"c5534a1803145f6344b04c437d436bd583852c78dd3937f4a73a2a39aa2d76b2","tests/data/invalid_offset2.zip":"0f0f3d654f303eaf90f599c0b0266be476ce34857cff932070a86e9853dcb4f9","tests/data/mimetype.zip":"aad4289745bd89016181a35653c9a483c6b9b632e06d002736c7040d61c562a2","tests/data/zip64_demo.zip":"223072a480f60d6a700e427b294e575ae2d6265f3e9881b647927f31d96c7e01","tests/end_to_end.rs":"ba69c247e2f555a954ae97615a46a9b21092671f7ff1abebaba058b30a53bb66","tests/invalid_date.rs":"72d5425ffe2887e05646ba56f5116ac760cbeeb7889da5c9be612fe57477bc94","tests/issue_234.rs":"1a3d68d79108140100709c188841c6bf54af8500c819072a440ec72df5d8ab26","tests/zip64_large.rs":"d4859f551be83c2ae3bd4a8e37c7e617fb54bb27310e725de6c7076c5e566d6b","tests/zip_comment_garbage.rs":"ab0e2e3ace1ca5459977a092ee96836f58c7f7a7cfc8de258ab448d8d24f1cbb","tests/zip_crypto.rs":"7f4f9670e5d971ac4234c7ab2cafecf43801baf0be0cfca6e34c651f6fc6a80d"},"package":"0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"385ad47ed19c64c42186eac68bedbf36c017077e41eafa6b13b2ecac2fc9699d","CODE_OF_CONDUCT.md":"77930b2129928632cae79e10d0863885b34729e4f144f3ae5443cff65997196a","Cargo.lock":"c70ccadfe0fb083a4bb7856df630cd9194a78641b6cb8d13cacd7675524aa989","Cargo.toml":"7cb213851ac9541dc7dd3ce163ef72c302985c9fb7d5bfed8859cb7988afd766","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"fc2e679d51b854f3c7836a6537b47b6014d7c419ff553ffb45b71b9ade460985","benches/read_entry.rs":"700235ee560887f33da56895d2a4da901c070b2a6a59aef90331046af4ddadad","benches/read_metadata.rs":"591e5adb9d36bf66da21d7e0d36a129c9bcf1331fa11714df8c53c860aee65ff","examples/extract.rs":"81f58da293553fe019319348e1d226a2d192480667877e72d77ab58812f5de1b","examples/extract_lorem.rs":"2d438706ca6e02468f362a54f4f2125598d2be1051e7ce40b71be58cfd703669","examples/file_info.rs":"20639234293511022938c8204488d182ccbcdfb59d962000acd8ac8f2f6db667","examples/stdin_info.rs":"5735801c9692a9b6ec35da6e6a65807db48b577068ab9df0018343df5161034b","examples/write_dir.rs":"224239e040c583f2e1ca4b1328ebe1a63b3c2213df6da8232cd62e004db05587","examples/write_sample.rs":"f723bf69676492599c2684aa995177f80e2aa922f1c9ae1681ed39e0a15959ad","src/aes.rs":"c1b19bdf15c75cc27b5657d1dc574b5c5ebcdc7ca2573e9909cc6ba1ffe7f6d8","src/aes_ctr.rs":"1b5e4ae423b1652353c56f436a50c3a7c27cf3b78138e09b29e2b0c054b8e827","src/compression.rs":"84f8ded41182155cfbdb1ce79b9dc84cae0a6e55557021cf9f2d7168d8913b48","src/cp437.rs":"e3a044ddefc947f6d9c26ba50ebd438955d90b8971ad8b15e5dd1194495f3b93","src/crc32.rs":"6c5a48834dfa1ab33590fcc63f4121ee6d3f8fbcc5018e905c4d8570096874cf","src/lib.rs":"9503371bc4978006c6f2b15dbf3a781dddf40923875480df068f06ff60159050","src/read.rs":"3b802c0c01da2e18efa8cbfb8c3ad91df315674424e93414a9b43d128d7628e9","src/read/stream.rs":"a5fba4cf1abacc3d7d8e0ee7734dd3d6f2f0a5a90fd9b595d8b18877a0f06a6d","src/result.rs":"7dc62da507ef2228313ed617d01f4d207eacb0b66352a497d24f04298e90e5df","src/spec.rs":"2a249aeb3c58ca475b5c7da6919cb61ac3cbe07b94a0cb3c730646d46fb265a8","src/types.rs":"e77ddc1dc8c8f45107688c7ea54559dd696e1e2532ea285f3c3810860bfa4e37","src/unstable.rs":"15ecc548d32da535834bd5c67ddd6ddcd9f4a81e786853661e3d07eea7c4aa23","src/write.rs":"ada88e695ba2e1ae295b183921613c6b81a192a9942da35bf5491ea0e140e99e","src/zipcrypto.rs":"a43d0c42fe78e395c4f66cd3e3c6380821637fc1951934294caa7572b2dc7b67","tests/aes_encryption.rs":"3733df1f5dcab4e9f9b9ec25cc7660f23c917759670e9b2e6fe77cfcd771faa9","tests/data/aes_archive.zip":"4abb3f304d1ab669453b7c4eae80db6ce8aff4ab91c8ab9a6edf90bbfede12f4","tests/data/comment_garbage.zip":"4a908af18691e50fc7773b34669a8ab6cb60875bee4d60fb7cd66d90eed55d2b","tests/data/files_and_dirs.zip":"e54cd8d084739f8d0b119d769c1263507b4da915cc38e4e2d3e4ef17c718f317","tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip":"c680ed5ad622aae23eea3b5d90145cb79550e413cc6e9a7b67bb1043851512ee","tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip":"7c272255e825aff7167dc8d1f2e1d16583e58347bb56ecf9879bdb07c6ad18e9","tests/data/invalid_offset.zip":"c5534a1803145f6344b04c437d436bd583852c78dd3937f4a73a2a39aa2d76b2","tests/data/invalid_offset2.zip":"0f0f3d654f303eaf90f599c0b0266be476ce34857cff932070a86e9853dcb4f9","tests/data/mimetype.zip":"aad4289745bd89016181a35653c9a483c6b9b632e06d002736c7040d61c562a2","tests/data/zip64_demo.zip":"223072a480f60d6a700e427b294e575ae2d6265f3e9881b647927f31d96c7e01","tests/end_to_end.rs":"ba69c247e2f555a954ae97615a46a9b21092671f7ff1abebaba058b30a53bb66","tests/invalid_date.rs":"72d5425ffe2887e05646ba56f5116ac760cbeeb7889da5c9be612fe57477bc94","tests/issue_234.rs":"48bbb0280b2cadfb30add0bc2eac730260ee4c0b98eda6c8f4efee499c894a4e","tests/zip64_large.rs":"d4859f551be83c2ae3bd4a8e37c7e617fb54bb27310e725de6c7076c5e566d6b","tests/zip_comment_garbage.rs":"ab0e2e3ace1ca5459977a092ee96836f58c7f7a7cfc8de258ab448d8d24f1cbb","tests/zip_crypto.rs":"9e1dc04a7fe627fa7ad3f31c7e70d5fa27759d583d63f8288208e1429dfacecb"},"package":"760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"} \ No newline at end of file
diff --git a/vendor/zip/CHANGELOG.md b/vendor/zip/CHANGELOG.md
index cd79e3913..96c6994fe 100644
--- a/vendor/zip/CHANGELOG.md
+++ b/vendor/zip/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## [0.6.6]
+### Changed
+
+- Updated `aes` dependency to `0.8.2` (https://github.com/zip-rs/zip/pull/354)
+
+## [0.6.5]
+### Changed
+
+- Added experimental [`zip::unstable::write::FileOptions::with_deprecated_encryption`] API to enable encrypting files with PKWARE encryption.
+
## [0.6.4]
### Changed
diff --git a/vendor/zip/Cargo.lock b/vendor/zip/Cargo.lock
index f0f4b2bd0..f1886669a 100644
--- a/vendor/zip/Cargo.lock
+++ b/vendor/zip/Cargo.lock
@@ -10,21 +10,20 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aes"
-version = "0.7.5"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
+checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
- "opaque-debug",
]
[[package]]
name = "base64ct"
-version = "1.5.3"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
+checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bencher"
@@ -34,9 +33,9 @@ checksum = "7dfdb4953a096c551ce9ace855a604d702e6e62d77fac690575ae347571717f5"
[[package]]
name = "block-buffer"
-version = "0.10.3"
+version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
@@ -70,9 +69,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.0.78"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
@@ -85,11 +84,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cipher"
-version = "0.3.0"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
- "generic-array",
+ "crypto-common",
+ "inout",
]
[[package]]
@@ -100,9 +100,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "cpufeatures"
-version = "0.2.5"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
dependencies = [
"libc",
]
@@ -118,9 +118,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.14"
+version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
dependencies = [
"cfg-if",
]
@@ -148,9 +148,9 @@ dependencies = [
[[package]]
name = "flate2"
-version = "1.0.25"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
+checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
dependencies = [
"crc32fast",
"libz-sys",
@@ -159,9 +159,9 @@ dependencies = [
[[package]]
name = "generic-array"
-version = "0.14.6"
+version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
@@ -169,9 +169,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
@@ -188,31 +188,40 @@ dependencies = [
]
[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "itoa"
-version = "1.0.5"
+version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "jobserver"
-version = "0.1.25"
+version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
+checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
dependencies = [
"libc",
]
[[package]]
name = "libc"
-version = "0.2.139"
+version = "0.2.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "libz-sys"
-version = "1.1.8"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
+checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
dependencies = [
"cc",
"pkg-config",
@@ -221,20 +230,14 @@ dependencies = [
[[package]]
name = "miniz_oxide"
-version = "0.6.2"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
-name = "opaque-debug"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
-
-[[package]]
name = "password-hash"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -259,9 +262,9 @@ dependencies = [
[[package]]
name = "pkg-config"
-version = "0.3.26"
+version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "rand_core"
@@ -280,9 +283,9 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.152"
+version = "1.0.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6"
[[package]]
name = "sha1"
@@ -314,9 +317,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "time"
-version = "0.3.17"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
dependencies = [
"itoa",
"serde",
@@ -326,15 +329,15 @@ dependencies = [
[[package]]
name = "time-core"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "time-macros"
-version = "0.2.6"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
dependencies = [
"time-core",
]
@@ -359,12 +362,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
-version = "2.3.2"
+version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
dependencies = [
"same-file",
- "winapi",
"winapi-util",
]
@@ -407,7 +409,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "zip"
-version = "0.6.4"
+version = "0.6.6"
dependencies = [
"aes",
"bencher",
@@ -447,9 +449,9 @@ dependencies = [
[[package]]
name = "zstd-sys"
-version = "2.0.5+zstd.1.5.2"
+version = "2.0.8+zstd.1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596"
+checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
dependencies = [
"cc",
"libc",
diff --git a/vendor/zip/Cargo.toml b/vendor/zip/Cargo.toml
index 7a1b656b2..da0180ec4 100644
--- a/vendor/zip/Cargo.toml
+++ b/vendor/zip/Cargo.toml
@@ -10,9 +10,10 @@
# See Cargo.toml.orig for the original contents.
[package]
-edition = "2018"
+edition = "2021"
+rust-version = "1.59.0"
name = "zip"
-version = "0.6.4"
+version = "0.6.6"
authors = [
"Mathijs van de Nes <git@mathijs.vd-nes.nl>",
"Marli Frost <marli@frost.red>",
@@ -38,7 +39,7 @@ name = "read_metadata"
harness = false
[dependencies.aes]
-version = "0.7.5"
+version = "0.8.2"
optional = true
[dependencies.byteorder]
diff --git a/vendor/zip/README.md b/vendor/zip/README.md
index 3754a7c0f..f06cdbb57 100644
--- a/vendor/zip/README.md
+++ b/vendor/zip/README.md
@@ -7,9 +7,6 @@ zip-rs
[Documentation](https://docs.rs/zip/0.6.3/zip/)
-> PSA: This version of the ZIP crate will not gain any new features,
-> and will only be updated if major security issues are found.
-
Info
----
@@ -35,14 +32,14 @@ With all default features:
```toml
[dependencies]
-zip = "0.6.4"
+zip = "0.6"
```
Without the default features:
```toml
[dependencies]
-zip = { version = "0.6.4", default-features = false }
+zip = { version = "0.6.6", default-features = false }
```
The features available are:
diff --git a/vendor/zip/src/aes_ctr.rs b/vendor/zip/src/aes_ctr.rs
index 0f34335cb..211727c0a 100644
--- a/vendor/zip/src/aes_ctr.rs
+++ b/vendor/zip/src/aes_ctr.rs
@@ -2,10 +2,11 @@
//!
//! This was implemented since the zip specification requires the mode to not use a nonce and uses a
//! different byte order (little endian) than NIST (big endian).
-//! See [AesCtrZipKeyStream](./struct.AesCtrZipKeyStream.html) for more information.
+//! See [AesCtrZipKeyStream] for more information.
use aes::cipher::generic_array::GenericArray;
-use aes::{BlockEncrypt, NewBlockCipher};
+// use aes::{BlockEncrypt, NewBlockCipher};
+use aes::cipher::{BlockEncrypt, KeyInit};
use byteorder::WriteBytesExt;
use std::{any, fmt};
@@ -82,7 +83,7 @@ where
impl<C> AesCtrZipKeyStream<C>
where
C: AesKind,
- C::Cipher: NewBlockCipher,
+ C::Cipher: KeyInit,
{
/// Creates a new zip variant AES-CTR key stream.
///
@@ -150,14 +151,14 @@ fn xor(dest: &mut [u8], src: &[u8]) {
#[cfg(test)]
mod tests {
use super::{Aes128, Aes192, Aes256, AesCipher, AesCtrZipKeyStream, AesKind};
- use aes::{BlockEncrypt, NewBlockCipher};
+ use aes::cipher::{BlockEncrypt, KeyInit};
/// Checks whether `crypt_in_place` produces the correct plaintext after one use and yields the
/// cipertext again after applying it again.
fn roundtrip<Aes>(key: &[u8], ciphertext: &mut [u8], expected_plaintext: &[u8])
where
Aes: AesKind,
- Aes::Cipher: NewBlockCipher + BlockEncrypt,
+ Aes::Cipher: KeyInit + BlockEncrypt,
{
let mut key_stream = AesCtrZipKeyStream::<Aes>::new(key);
diff --git a/vendor/zip/src/lib.rs b/vendor/zip/src/lib.rs
index 0fee99cc8..e2228e5b1 100644
--- a/vendor/zip/src/lib.rs
+++ b/vendor/zip/src/lib.rs
@@ -42,3 +42,14 @@ mod spec;
mod types;
pub mod write;
mod zipcrypto;
+
+/// Unstable APIs
+///
+/// All APIs accessible by importing this module are unstable; They may be changed in patch releases.
+/// You MUST you an exact version specifier in `Cargo.toml`, to indicate the version of this API you're using:
+///
+/// ```toml
+/// [dependencies]
+/// zip = "=0.6.6"
+/// ```
+pub mod unstable;
diff --git a/vendor/zip/src/read.rs b/vendor/zip/src/read.rs
index dad20c260..b702b4f21 100644
--- a/vendor/zip/src/read.rs
+++ b/vendor/zip/src/read.rs
@@ -13,7 +13,7 @@ use byteorder::{LittleEndian, ReadBytesExt};
use std::borrow::Cow;
use std::collections::HashMap;
use std::io::{self, prelude::*};
-use std::path::{Component, Path};
+use std::path::Path;
use std::sync::Arc;
#[cfg(any(
@@ -29,10 +29,8 @@ use bzip2::read::BzDecoder;
#[cfg(feature = "zstd")]
use zstd::stream::read::Decoder as ZstdDecoder;
-mod ffi {
- pub const S_IFDIR: u32 = 0o0040000;
- pub const S_IFREG: u32 = 0o0100000;
-}
+/// Provides high level API for reading from a stream.
+pub(crate) mod stream;
// Put the struct declaration in a private module to convince rustdoc to display ZipArchive nicely
pub(crate) mod zip_archive {
@@ -650,12 +648,22 @@ pub(crate) fn central_header_to_zip_file<R: Read + io::Seek>(
archive_offset: u64,
) -> ZipResult<ZipFileData> {
let central_header_start = reader.stream_position()?;
+
// Parse central header
let signature = reader.read_u32::<LittleEndian>()?;
if signature != spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE {
- return Err(ZipError::InvalidArchive("Invalid Central Directory header"));
+ Err(ZipError::InvalidArchive("Invalid Central Directory header"))
+ } else {
+ central_header_to_zip_file_inner(reader, archive_offset, central_header_start)
}
+}
+/// Parse a central directory entry to collect the information for the file.
+fn central_header_to_zip_file_inner<R: Read>(
+ reader: &mut R,
+ archive_offset: u64,
+ central_header_start: u64,
+) -> ZipResult<ZipFileData> {
let version_made_by = reader.read_u16::<LittleEndian>()?;
let _version_to_extract = reader.read_u16::<LittleEndian>()?;
let flags = reader.read_u16::<LittleEndian>()?;
@@ -896,20 +904,7 @@ impl<'a> ZipFile<'a> {
/// to path-based exploits. It is recommended over
/// [`ZipFile::mangled_name`].
pub fn enclosed_name(&self) -> Option<&Path> {
- if self.data.file_name.contains('\0') {
- return None;
- }
- let path = Path::new(&self.data.file_name);
- let mut depth = 0usize;
- for component in path.components() {
- match component {
- Component::Prefix(_) | Component::RootDir => return None,
- Component::ParentDir => depth = depth.checked_sub(1)?,
- Component::Normal(_) => depth += 1,
- Component::CurDir => (),
- }
- }
- Some(path)
+ self.data.enclosed_name()
}
/// Get the comment of the file
@@ -952,27 +947,7 @@ impl<'a> ZipFile<'a> {
/// Get unix mode for the file
pub fn unix_mode(&self) -> Option<u32> {
- if self.data.external_attributes == 0 {
- return None;
- }
-
- match self.data.system {
- System::Unix => Some(self.data.external_attributes >> 16),
- System::Dos => {
- // Interpret MS-DOS directory bit
- let mut mode = if 0x10 == (self.data.external_attributes & 0x10) {
- ffi::S_IFDIR | 0o0775
- } else {
- ffi::S_IFREG | 0o0664
- };
- if 0x01 == (self.data.external_attributes & 0x01) {
- // Read-only bit; strip write permissions
- mode &= 0o0555;
- }
- Some(mode)
- }
- _ => None,
- }
+ self.data.unix_mode()
}
/// Get the CRC32 hash of the original file
@@ -1029,10 +1004,9 @@ impl<'a> Drop for ZipFile<'a> {
match reader.read(&mut buffer) {
Ok(0) => break,
Ok(_) => (),
- Err(e) => panic!(
- "Could not consume all of the output of the current ZipFile: {:?}",
- e
- ),
+ Err(e) => {
+ panic!("Could not consume all of the output of the current ZipFile: {e:?}")
+ }
}
}
}
diff --git a/vendor/zip/src/read/stream.rs b/vendor/zip/src/read/stream.rs
new file mode 100644
index 000000000..5a01b23f9
--- /dev/null
+++ b/vendor/zip/src/read/stream.rs
@@ -0,0 +1,372 @@
+use std::fs;
+use std::io::{self, Read};
+use std::path::Path;
+
+use super::{
+ central_header_to_zip_file_inner, read_zipfile_from_stream, spec, ZipError, ZipFile,
+ ZipFileData, ZipResult,
+};
+
+use byteorder::{LittleEndian, ReadBytesExt};
+
+/// Stream decoder for zip.
+#[derive(Debug)]
+pub struct ZipStreamReader<R>(R);
+
+impl<R> ZipStreamReader<R> {
+ /// Create a new ZipStreamReader
+ pub fn new(reader: R) -> Self {
+ Self(reader)
+ }
+}
+
+impl<R: Read> ZipStreamReader<R> {
+ fn parse_central_directory(&mut self) -> ZipResult<Option<ZipStreamFileMetadata>> {
+ // Give archive_offset and central_header_start dummy value 0, since
+ // they are not used in the output.
+ let archive_offset = 0;
+ let central_header_start = 0;
+
+ // Parse central header
+ let signature = self.0.read_u32::<LittleEndian>()?;
+ if signature != spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE {
+ Ok(None)
+ } else {
+ central_header_to_zip_file_inner(&mut self.0, archive_offset, central_header_start)
+ .map(ZipStreamFileMetadata)
+ .map(Some)
+ }
+ }
+
+ /// Iteraate over the stream and extract all file and their
+ /// metadata.
+ pub fn visit<V: ZipStreamVisitor>(mut self, visitor: &mut V) -> ZipResult<()> {
+ while let Some(mut file) = read_zipfile_from_stream(&mut self.0)? {
+ visitor.visit_file(&mut file)?;
+ }
+
+ while let Some(metadata) = self.parse_central_directory()? {
+ visitor.visit_additional_metadata(&metadata)?;
+ }
+
+ Ok(())
+ }
+
+ /// Extract a Zip archive into a directory, overwriting files if they
+ /// already exist. Paths are sanitized with [`ZipFile::enclosed_name`].
+ ///
+ /// Extraction is not atomic; If an error is encountered, some of the files
+ /// may be left on disk.
+ pub fn extract<P: AsRef<Path>>(self, directory: P) -> ZipResult<()> {
+ struct Extractor<'a>(&'a Path);
+ impl ZipStreamVisitor for Extractor<'_> {
+ fn visit_file(&mut self, file: &mut ZipFile<'_>) -> ZipResult<()> {
+ let filepath = file
+ .enclosed_name()
+ .ok_or(ZipError::InvalidArchive("Invalid file path"))?;
+
+ let outpath = self.0.join(filepath);
+
+ if file.name().ends_with('/') {
+ fs::create_dir_all(&outpath)?;
+ } else {
+ if let Some(p) = outpath.parent() {
+ fs::create_dir_all(p)?;
+ }
+ let mut outfile = fs::File::create(&outpath)?;
+ io::copy(file, &mut outfile)?;
+ }
+
+ Ok(())
+ }
+
+ #[allow(unused)]
+ fn visit_additional_metadata(
+ &mut self,
+ metadata: &ZipStreamFileMetadata,
+ ) -> ZipResult<()> {
+ #[cfg(unix)]
+ {
+ let filepath = metadata
+ .enclosed_name()
+ .ok_or(ZipError::InvalidArchive("Invalid file path"))?;
+
+ let outpath = self.0.join(filepath);
+
+ use std::os::unix::fs::PermissionsExt;
+ if let Some(mode) = metadata.unix_mode() {
+ fs::set_permissions(outpath, fs::Permissions::from_mode(mode))?;
+ }
+ }
+
+ Ok(())
+ }
+ }
+
+ self.visit(&mut Extractor(directory.as_ref()))
+ }
+}
+
+/// Visitor for ZipStreamReader
+pub trait ZipStreamVisitor {
+ /// * `file` - contains the content of the file and most of the metadata,
+ /// except:
+ /// - `comment`: set to an empty string
+ /// - `data_start`: set to 0
+ /// - `external_attributes`: `unix_mode()`: will return None
+ fn visit_file(&mut self, file: &mut ZipFile<'_>) -> ZipResult<()>;
+
+ /// This function is guranteed to be called after all `visit_file`s.
+ ///
+ /// * `metadata` - Provides missing metadata in `visit_file`.
+ fn visit_additional_metadata(&mut self, metadata: &ZipStreamFileMetadata) -> ZipResult<()>;
+}
+
+/// Additional metadata for the file.
+#[derive(Debug)]
+pub struct ZipStreamFileMetadata(ZipFileData);
+
+impl ZipStreamFileMetadata {
+ /// Get the name of the file
+ ///
+ /// # Warnings
+ ///
+ /// It is dangerous to use this name directly when extracting an archive.
+ /// It may contain an absolute path (`/etc/shadow`), or break out of the
+ /// current directory (`../runtime`). Carelessly writing to these paths
+ /// allows an attacker to craft a ZIP archive that will overwrite critical
+ /// files.
+ ///
+ /// You can use the [`ZipFile::enclosed_name`] method to validate the name
+ /// as a safe path.
+ pub fn name(&self) -> &str {
+ &self.0.file_name
+ }
+
+ /// Get the name of the file, in the raw (internal) byte representation.
+ ///
+ /// The encoding of this data is currently undefined.
+ pub fn name_raw(&self) -> &[u8] {
+ &self.0.file_name_raw
+ }
+
+ /// Rewrite the path, ignoring any path components with special meaning.
+ ///
+ /// - Absolute paths are made relative
+ /// - [`ParentDir`]s are ignored
+ /// - Truncates the filename at a NULL byte
+ ///
+ /// This is appropriate if you need to be able to extract *something* from
+ /// any archive, but will easily misrepresent trivial paths like
+ /// `foo/../bar` as `foo/bar` (instead of `bar`). Because of this,
+ /// [`ZipFile::enclosed_name`] is the better option in most scenarios.
+ ///
+ /// [`ParentDir`]: `Component::ParentDir`
+ pub fn mangled_name(&self) -> ::std::path::PathBuf {
+ self.0.file_name_sanitized()
+ }
+
+ /// Ensure the file path is safe to use as a [`Path`].
+ ///
+ /// - It can't contain NULL bytes
+ /// - It can't resolve to a path outside the current directory
+ /// > `foo/../bar` is fine, `foo/../../bar` is not.
+ /// - It can't be an absolute path
+ ///
+ /// This will read well-formed ZIP files correctly, and is resistant
+ /// to path-based exploits. It is recommended over
+ /// [`ZipFile::mangled_name`].
+ pub fn enclosed_name(&self) -> Option<&Path> {
+ self.0.enclosed_name()
+ }
+
+ /// Returns whether the file is actually a directory
+ pub fn is_dir(&self) -> bool {
+ self.name()
+ .chars()
+ .rev()
+ .next()
+ .map_or(false, |c| c == '/' || c == '\\')
+ }
+
+ /// Returns whether the file is a regular file
+ pub fn is_file(&self) -> bool {
+ !self.is_dir()
+ }
+
+ /// Get the comment of the file
+ pub fn comment(&self) -> &str {
+ &self.0.file_comment
+ }
+
+ /// Get the starting offset of the data of the compressed file
+ pub fn data_start(&self) -> u64 {
+ self.0.data_start.load()
+ }
+
+ /// Get unix mode for the file
+ pub fn unix_mode(&self) -> Option<u32> {
+ self.0.unix_mode()
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use std::collections::BTreeSet;
+ use std::io;
+
+ struct DummyVisitor;
+ impl ZipStreamVisitor for DummyVisitor {
+ fn visit_file(&mut self, _file: &mut ZipFile<'_>) -> ZipResult<()> {
+ Ok(())
+ }
+
+ fn visit_additional_metadata(
+ &mut self,
+ _metadata: &ZipStreamFileMetadata,
+ ) -> ZipResult<()> {
+ Ok(())
+ }
+ }
+
+ #[derive(Default, Debug, Eq, PartialEq)]
+ struct CounterVisitor(u64, u64);
+ impl ZipStreamVisitor for CounterVisitor {
+ fn visit_file(&mut self, _file: &mut ZipFile<'_>) -> ZipResult<()> {
+ self.0 += 1;
+ Ok(())
+ }
+
+ fn visit_additional_metadata(
+ &mut self,
+ _metadata: &ZipStreamFileMetadata,
+ ) -> ZipResult<()> {
+ self.1 += 1;
+ Ok(())
+ }
+ }
+
+ #[test]
+ fn invalid_offset() {
+ ZipStreamReader::new(io::Cursor::new(include_bytes!(
+ "../../tests/data/invalid_offset.zip"
+ )))
+ .visit(&mut DummyVisitor)
+ .unwrap_err();
+ }
+
+ #[test]
+ fn invalid_offset2() {
+ ZipStreamReader::new(io::Cursor::new(include_bytes!(
+ "../../tests/data/invalid_offset2.zip"
+ )))
+ .visit(&mut DummyVisitor)
+ .unwrap_err();
+ }
+
+ #[test]
+ fn zip_read_streaming() {
+ let reader = ZipStreamReader::new(io::Cursor::new(include_bytes!(
+ "../../tests/data/mimetype.zip"
+ )));
+
+ #[derive(Default)]
+ struct V {
+ filenames: BTreeSet<Box<str>>,
+ }
+ impl ZipStreamVisitor for V {
+ fn visit_file(&mut self, file: &mut ZipFile<'_>) -> ZipResult<()> {
+ if file.is_file() {
+ self.filenames.insert(file.name().into());
+ }
+
+ Ok(())
+ }
+ fn visit_additional_metadata(
+ &mut self,
+ metadata: &ZipStreamFileMetadata,
+ ) -> ZipResult<()> {
+ if metadata.is_file() {
+ assert!(
+ self.filenames.contains(metadata.name()),
+ "{} is missing its file content",
+ metadata.name()
+ );
+ }
+
+ Ok(())
+ }
+ }
+
+ reader.visit(&mut V::default()).unwrap();
+ }
+
+ #[test]
+ fn file_and_dir_predicates() {
+ let reader = ZipStreamReader::new(io::Cursor::new(include_bytes!(
+ "../../tests/data/files_and_dirs.zip"
+ )));
+
+ #[derive(Default)]
+ struct V {
+ filenames: BTreeSet<Box<str>>,
+ }
+ impl ZipStreamVisitor for V {
+ fn visit_file(&mut self, file: &mut ZipFile<'_>) -> ZipResult<()> {
+ let full_name = file.enclosed_name().unwrap();
+ let file_name = full_name.file_name().unwrap().to_str().unwrap();
+ assert!(
+ (file_name.starts_with("dir") && file.is_dir())
+ || (file_name.starts_with("file") && file.is_file())
+ );
+
+ if file.is_file() {
+ self.filenames.insert(file.name().into());
+ }
+
+ Ok(())
+ }
+ fn visit_additional_metadata(
+ &mut self,
+ metadata: &ZipStreamFileMetadata,
+ ) -> ZipResult<()> {
+ if metadata.is_file() {
+ assert!(
+ self.filenames.contains(metadata.name()),
+ "{} is missing its file content",
+ metadata.name()
+ );
+ }
+
+ Ok(())
+ }
+ }
+
+ reader.visit(&mut V::default()).unwrap();
+ }
+
+ /// test case to ensure we don't preemptively over allocate based on the
+ /// declared number of files in the CDE of an invalid zip when the number of
+ /// files declared is more than the alleged offset in the CDE
+ #[test]
+ fn invalid_cde_number_of_files_allocation_smaller_offset() {
+ ZipStreamReader::new(io::Cursor::new(include_bytes!(
+ "../../tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip"
+ )))
+ .visit(&mut DummyVisitor)
+ .unwrap_err();
+ }
+
+ /// test case to ensure we don't preemptively over allocate based on the
+ /// declared number of files in the CDE of an invalid zip when the number of
+ /// files declared is less than the alleged offset in the CDE
+ #[test]
+ fn invalid_cde_number_of_files_allocation_greater_offset() {
+ ZipStreamReader::new(io::Cursor::new(include_bytes!(
+ "../../tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip"
+ )))
+ .visit(&mut DummyVisitor)
+ .unwrap_err();
+ }
+}
diff --git a/vendor/zip/src/types.rs b/vendor/zip/src/types.rs
index ad3a5700b..c3d0a45db 100644
--- a/vendor/zip/src/types.rs
+++ b/vendor/zip/src/types.rs
@@ -1,6 +1,6 @@
//! Types that specify what is contained in a ZIP.
-#[cfg(feature = "time")]
-use std::convert::{TryFrom, TryInto};
+use std::path;
+
#[cfg(not(any(
all(target_arch = "arm", target_pointer_width = "32"),
target_arch = "mips",
@@ -12,6 +12,11 @@ use std::time::SystemTime;
#[cfg(doc)]
use {crate::read::ZipFile, crate::write::FileOptions};
+mod ffi {
+ pub const S_IFDIR: u32 = 0o0040000;
+ pub const S_IFREG: u32 = 0o0100000;
+}
+
#[cfg(any(
all(target_arch = "arm", target_pointer_width = "32"),
target_arch = "mips",
@@ -375,6 +380,48 @@ impl ZipFileData {
})
}
+ pub(crate) fn enclosed_name(&self) -> Option<&path::Path> {
+ if self.file_name.contains('\0') {
+ return None;
+ }
+ let path = path::Path::new(&self.file_name);
+ let mut depth = 0usize;
+ for component in path.components() {
+ match component {
+ path::Component::Prefix(_) | path::Component::RootDir => return None,
+ path::Component::ParentDir => depth = depth.checked_sub(1)?,
+ path::Component::Normal(_) => depth += 1,
+ path::Component::CurDir => (),
+ }
+ }
+ Some(path)
+ }
+
+ /// Get unix mode for the file
+ pub(crate) fn unix_mode(&self) -> Option<u32> {
+ if self.external_attributes == 0 {
+ return None;
+ }
+
+ match self.system {
+ System::Unix => Some(self.external_attributes >> 16),
+ System::Dos => {
+ // Interpret MS-DOS directory bit
+ let mut mode = if 0x10 == (self.external_attributes & 0x10) {
+ ffi::S_IFDIR | 0o0775
+ } else {
+ ffi::S_IFREG | 0o0664
+ };
+ if 0x01 == (self.external_attributes & 0x01) {
+ // Read-only bit; strip write permissions
+ mode &= 0o0555;
+ }
+ Some(mode)
+ }
+ _ => None,
+ }
+ }
+
pub fn zip64_extension(&self) -> bool {
self.uncompressed_size > 0xFFFFFFFF
|| self.compressed_size > 0xFFFFFFFF
@@ -510,27 +557,6 @@ mod test {
#[cfg(feature = "time")]
#[test]
- fn datetime_from_time_bounds() {
- use std::convert::TryFrom;
-
- use super::DateTime;
- use time::macros::datetime;
-
- // 1979-12-31 23:59:59
- assert!(DateTime::try_from(datetime!(1979-12-31 23:59:59 UTC)).is_err());
-
- // 1980-01-01 00:00:00
- assert!(DateTime::try_from(datetime!(1980-01-01 00:00:00 UTC)).is_ok());
-
- // 2107-12-31 23:59:59
- assert!(DateTime::try_from(datetime!(2107-12-31 23:59:59 UTC)).is_ok());
-
- // 2108-01-01 00:00:00
- assert!(DateTime::try_from(datetime!(2108-01-01 00:00:00 UTC)).is_err());
- }
-
- #[cfg(feature = "time")]
- #[test]
fn datetime_try_from_bounds() {
use std::convert::TryFrom;
diff --git a/vendor/zip/src/unstable.rs b/vendor/zip/src/unstable.rs
new file mode 100644
index 000000000..f8b46a970
--- /dev/null
+++ b/vendor/zip/src/unstable.rs
@@ -0,0 +1,20 @@
+/// Provides high level API for reading from a stream.
+pub mod stream {
+ pub use crate::read::stream::*;
+}
+/// Types for creating ZIP archives.
+pub mod write {
+ use crate::write::FileOptions;
+ /// Unstable methods for [`FileOptions`].
+ pub trait FileOptionsExt {
+ /// Write the file with the given password using the deprecated ZipCrypto algorithm.
+ ///
+ /// This is not recommended for new archives, as ZipCrypto is not secure.
+ fn with_deprecated_encryption(self, password: &[u8]) -> Self;
+ }
+ impl FileOptionsExt for FileOptions {
+ fn with_deprecated_encryption(self, password: &[u8]) -> Self {
+ self.with_deprecated_encryption(password)
+ }
+ }
+} \ No newline at end of file
diff --git a/vendor/zip/src/write.rs b/vendor/zip/src/write.rs
index 14252b4d5..4cdc031b0 100644
--- a/vendor/zip/src/write.rs
+++ b/vendor/zip/src/write.rs
@@ -29,19 +29,37 @@ use time::OffsetDateTime;
#[cfg(feature = "zstd")]
use zstd::stream::write::Encoder as ZstdEncoder;
+enum MaybeEncrypted<W> {
+ Unencrypted(W),
+ Encrypted(crate::zipcrypto::ZipCryptoWriter<W>),
+}
+impl<W: Write> Write for MaybeEncrypted<W> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ match self {
+ MaybeEncrypted::Unencrypted(w) => w.write(buf),
+ MaybeEncrypted::Encrypted(w) => w.write(buf),
+ }
+ }
+ fn flush(&mut self) -> io::Result<()> {
+ match self {
+ MaybeEncrypted::Unencrypted(w) => w.flush(),
+ MaybeEncrypted::Encrypted(w) => w.flush(),
+ }
+ }
+}
enum GenericZipWriter<W: Write + io::Seek> {
Closed,
- Storer(W),
+ Storer(MaybeEncrypted<W>),
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
- Deflater(DeflateEncoder<W>),
+ Deflater(DeflateEncoder<MaybeEncrypted<W>>),
#[cfg(feature = "bzip2")]
- Bzip2(BzEncoder<W>),
+ Bzip2(BzEncoder<MaybeEncrypted<W>>),
#[cfg(feature = "zstd")]
- Zstd(ZstdEncoder<'static, W>),
+ Zstd(ZstdEncoder<'static, MaybeEncrypted<W>>),
}
// Put the struct declaration in a private module to convince rustdoc to display ZipWriter nicely
pub(crate) mod zip_writer {
@@ -108,6 +126,7 @@ pub struct FileOptions {
last_modified_time: DateTime,
permissions: Option<u32>,
large_file: bool,
+ encrypt_with: Option<crate::zipcrypto::ZipCryptoKeys>,
}
impl FileOptions {
@@ -171,6 +190,10 @@ impl FileOptions {
self.large_file = large;
self
}
+ pub(crate) fn with_deprecated_encryption(mut self, password: &[u8]) -> FileOptions {
+ self.encrypt_with = Some(crate::zipcrypto::ZipCryptoKeys::derive(password));
+ self
+ }
}
impl Default for FileOptions {
@@ -196,6 +219,7 @@ impl Default for FileOptions {
last_modified_time: DateTime::default(),
permissions: None,
large_file: false,
+ encrypt_with: None,
}
}
}
@@ -284,7 +308,7 @@ impl<A: Read + Write + io::Seek> ZipWriter<A> {
let _ = readwriter.seek(io::SeekFrom::Start(directory_start)); // seek directory_start to overwrite it
Ok(ZipWriter {
- inner: GenericZipWriter::Storer(readwriter),
+ inner: GenericZipWriter::Storer(MaybeEncrypted::Unencrypted(readwriter)),
files,
stats: Default::default(),
writing_to_file: false,
@@ -302,7 +326,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
/// Before writing to this object, the [`ZipWriter::start_file`] function should be called.
pub fn new(inner: W) -> ZipWriter<W> {
ZipWriter {
- inner: GenericZipWriter::Storer(inner),
+ inner: GenericZipWriter::Storer(MaybeEncrypted::Unencrypted(inner)),
files: Vec::new(),
stats: Default::default(),
writing_to_file: false,
@@ -355,7 +379,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
let mut file = ZipFileData {
system: System::Unix,
version_made_by: DEFAULT_VERSION,
- encrypted: false,
+ encrypted: options.encrypt_with.is_some(),
using_data_descriptor: false,
compression_method: options.compression_method,
compression_level: options.compression_level,
@@ -385,7 +409,13 @@ impl<W: Write + io::Seek> ZipWriter<W> {
self.files.push(file);
}
+ if let Some(keys) = options.encrypt_with {
+ let mut zipwriter = crate::zipcrypto::ZipCryptoWriter { writer: core::mem::replace(&mut self.inner, GenericZipWriter::Closed).unwrap(), buffer: vec![], keys };
+ let mut crypto_header = [0u8; 12];
+ zipwriter.write_all(&crypto_header)?;
+ self.inner = GenericZipWriter::Storer(MaybeEncrypted::Encrypted(zipwriter));
+ }
Ok(())
}
@@ -395,6 +425,14 @@ impl<W: Write + io::Seek> ZipWriter<W> {
self.end_extra_data()?;
}
self.inner.switch_to(CompressionMethod::Stored, None)?;
+ match core::mem::replace(&mut self.inner, GenericZipWriter::Closed) {
+ GenericZipWriter::Storer(MaybeEncrypted::Encrypted(writer)) => {
+ let crc32 = self.stats.hasher.clone().finalize();
+ self.inner = GenericZipWriter::Storer(MaybeEncrypted::Unencrypted(writer.finish(crc32)?))
+ }
+ GenericZipWriter::Storer(w) => self.inner = GenericZipWriter::Storer(w),
+ _ => unreachable!()
+ }
let writer = self.inner.get_plain();
if !self.writing_raw {
@@ -699,7 +737,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
/// Add a directory entry.
///
- /// You can't write data to the file afterwards.
+ /// As directories have no content, you must not call [`ZipWriter::write`] before adding a new file.
pub fn add_directory<S>(&mut self, name: S, mut options: FileOptions) -> ZipResult<()>
where
S: Into<String>,
@@ -985,8 +1023,8 @@ impl<W: Write + io::Seek> GenericZipWriter<W> {
fn get_plain(&mut self) -> &mut W {
match *self {
- GenericZipWriter::Storer(ref mut w) => w,
- _ => panic!("Should have switched to stored beforehand"),
+ GenericZipWriter::Storer(MaybeEncrypted::Unencrypted(ref mut w)) => w,
+ _ => panic!("Should have switched to stored and unencrypted beforehand"),
}
}
@@ -1009,8 +1047,8 @@ impl<W: Write + io::Seek> GenericZipWriter<W> {
fn unwrap(self) -> W {
match self {
- GenericZipWriter::Storer(w) => w,
- _ => panic!("Should have switched to stored beforehand"),
+ GenericZipWriter::Storer(MaybeEncrypted::Unencrypted(w)) => w,
+ _ => panic!("Should have switched to stored and unencrypted beforehand"),
}
}
}
@@ -1058,7 +1096,7 @@ fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipR
1u16 << 11
} else {
0
- };
+ } | if file.encrypted { 1u16 << 0 } else { 0 };
writer.write_u16::<LittleEndian>(flag)?;
// Compression method
#[allow(deprecated)]
@@ -1133,7 +1171,7 @@ fn write_central_directory_header<T: Write>(writer: &mut T, file: &ZipFileData)
1u16 << 11
} else {
0
- };
+ } | if file.encrypted { 1u16 << 0 } else { 0 };
writer.write_u16::<LittleEndian>(flag)?;
// compression method
#[allow(deprecated)]
@@ -1428,6 +1466,7 @@ mod test {
last_modified_time: DateTime::default(),
permissions: Some(33188),
large_file: false,
+ encrypt_with: None,
};
writer.start_file("mimetype", options).unwrap();
writer
diff --git a/vendor/zip/src/zipcrypto.rs b/vendor/zip/src/zipcrypto.rs
index 91d403951..c3696e4d7 100644
--- a/vendor/zip/src/zipcrypto.rs
+++ b/vendor/zip/src/zipcrypto.rs
@@ -6,7 +6,8 @@
use std::num::Wrapping;
/// A container to hold the current key state
-struct ZipCryptoKeys {
+#[derive(Clone, Copy)]
+pub(crate) struct ZipCryptoKeys {
key_0: Wrapping<u32>,
key_1: Wrapping<u32>,
key_2: Wrapping<u32>,
@@ -49,6 +50,13 @@ impl ZipCryptoKeys {
fn crc32(crc: Wrapping<u32>, input: u8) -> Wrapping<u32> {
(crc >> 8) ^ Wrapping(CRCTABLE[((crc & Wrapping(0xff)).0 as u8 ^ input) as usize])
}
+ pub(crate) fn derive(password: &[u8]) -> ZipCryptoKeys {
+ let mut keys = ZipCryptoKeys::new();
+ for byte in password.iter() {
+ keys.update(*byte);
+ }
+ keys
+ }
}
/// A ZipCrypto reader with unverified password
@@ -70,17 +78,10 @@ impl<R: std::io::Read> ZipCryptoReader<R> {
/// would be impossible to decrypt files that were encrypted with a
/// password byte sequence that is unrepresentable in UTF-8.
pub fn new(file: R, password: &[u8]) -> ZipCryptoReader<R> {
- let mut result = ZipCryptoReader {
+ ZipCryptoReader {
file,
- keys: ZipCryptoKeys::new(),
- };
-
- // Key the cipher by updating the keys with the password.
- for byte in password.iter() {
- result.keys.update(*byte);
+ keys: ZipCryptoKeys::derive(password),
}
-
- result
}
/// Read the ZipCrypto header bytes and validate the password.
@@ -122,6 +123,31 @@ impl<R: std::io::Read> ZipCryptoReader<R> {
Ok(Some(ZipCryptoReaderValid { reader: self }))
}
}
+pub(crate) struct ZipCryptoWriter<W> {
+ pub(crate) writer: W,
+ pub(crate) buffer: Vec<u8>,
+ pub(crate) keys: ZipCryptoKeys,
+}
+impl<W: std::io::Write> ZipCryptoWriter<W> {
+ pub(crate) fn finish(mut self, crc32: u32) -> std::io::Result<W> {
+ self.buffer[11] = (crc32 >> 24) as u8;
+ for byte in self.buffer.iter_mut() {
+ *byte = self.keys.encrypt_byte(*byte);
+ }
+ self.writer.write_all(&self.buffer)?;
+ self.writer.flush()?;
+ Ok(self.writer)
+ }
+}
+impl<W: std::io::Write> std::io::Write for ZipCryptoWriter<W> {
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ self.buffer.extend_from_slice(buf);
+ Ok(buf.len())
+ }
+ fn flush(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+}
/// A ZipCrypto reader with verified password
pub struct ZipCryptoReaderValid<R> {
diff --git a/vendor/zip/tests/issue_234.rs b/vendor/zip/tests/issue_234.rs
index bd01d1d08..f8c1d2c81 100644
--- a/vendor/zip/tests/issue_234.rs
+++ b/vendor/zip/tests/issue_234.rs
@@ -26,6 +26,6 @@ fn invalid_header() {
let archive = zip::ZipArchive::new(reader);
match archive {
Err(ZipError::InvalidArchive(_)) => {}
- value => panic!("Unexpected value: {:?}", value),
+ value => panic!("Unexpected value: {value:?}"),
}
}
diff --git a/vendor/zip/tests/zip_crypto.rs b/vendor/zip/tests/zip_crypto.rs
index 6c4d6b811..d831c1e62 100644
--- a/vendor/zip/tests/zip_crypto.rs
+++ b/vendor/zip/tests/zip_crypto.rs
@@ -21,6 +21,23 @@ use std::io::Cursor;
use std::io::Read;
#[test]
+fn encrypting_file() {
+ use zip::unstable::write::FileOptionsExt;
+ use std::io::{Read, Write};
+ let mut buf = vec![0; 2048];
+ let mut archive = zip::write::ZipWriter::new(std::io::Cursor::new(&mut buf));
+ archive.start_file("name", zip::write::FileOptions::default().with_deprecated_encryption(b"password")).unwrap();
+ archive.write_all(b"test").unwrap();
+ archive.finish().unwrap();
+ drop(archive);
+ let mut archive = zip::ZipArchive::new(std::io::Cursor::new(&mut buf)).unwrap();
+ let mut file = archive.by_index_decrypt(0, b"password").unwrap().unwrap();
+ let mut buf = Vec::new();
+ file.read_to_end(&mut buf).unwrap();
+ assert_eq!(buf, b"test");
+
+}
+#[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,