aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2022-12-19 12:28:35 +0100
committerJeff Vander Stoep <jeffv@google.com>2022-12-19 12:29:02 +0100
commite1b598396a56f229babc3245b67fbae386726d42 (patch)
treee6b7e539d06b28d1944fa5b03ed723b4c68941b0
parentb40b0b329eef88b8b32b667b0009bd309d1455bf (diff)
downloadzip-e1b598396a56f229babc3245b67fbae386726d42.tar.gz
Upgrade zip to 0.6.3main-16k-with-phones
This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update rust/crates/zip For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md Test: TreeHugger Change-Id: Iae74ec57218a02d84073321972326ce530365dbc
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--.github/workflows/ci.yaml18
-rw-r--r--Android.bp2
-rw-r--r--Cargo.lock.saved457
-rw-r--r--Cargo.toml51
-rw-r--r--Cargo.toml.orig12
-rw-r--r--METADATA12
-rw-r--r--README.md29
-rw-r--r--benches/read_metadata.rs41
-rw-r--r--src/read.rs48
-rw-r--r--src/write.rs124
-rw-r--r--tests/data/invalid_cde_number_of_files_allocation_greater_offset.zipbin0 -> 124 bytes
-rw-r--r--tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zipbin0 -> 212 bytes
13 files changed, 760 insertions, 36 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index b50dc02..1e6556d 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "4f7609cec700765525a537747c8f340dd1090aa0"
+ "sha1": "1774bb872b6de398a75f3855457bb78fbfab4b5d"
},
"path_in_vcs": ""
} \ No newline at end of file
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 6f0e4b9..35d4a6e 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
- rust: [stable, 1.54.0]
+ rust: [stable, 1.59.0]
steps:
- uses: actions/checkout@master
@@ -74,3 +74,19 @@ jobs:
- name: Docs
run: cargo doc
+
+ fuzz:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions-rs/toolchain@v1
+ with:
+ profile: minimal
+ toolchain: nightly
+ override: true
+
+ - run: cargo install cargo-fuzz
+ - name: compile fuzz
+ run: |
+ cargo fuzz build fuzz_read
diff --git a/Android.bp b/Android.bp
index c0b2349..2e06d86 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,7 @@ rust_library {
host_supported: true,
crate_name: "zip",
cargo_env_compat: true,
- cargo_pkg_version: "0.6.2",
+ cargo_pkg_version: "0.6.3",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
diff --git a/Cargo.lock.saved b/Cargo.lock.saved
new file mode 100644
index 0000000..1da5fdf
--- /dev/null
+++ b/Cargo.lock.saved
@@ -0,0 +1,457 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aes"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+ "opaque-debug",
+]
+
+[[package]]
+name = "base64ct"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b"
+
+[[package]]
+name = "bencher"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dfdb4953a096c551ce9ace855a604d702e6e62d77fac690575ae347571717f5"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bzip2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0"
+dependencies = [
+ "bzip2-sys",
+ "libc",
+]
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+dependencies = [
+ "jobserver",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "constant_time_eq"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+dependencies = [
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
+dependencies = [
+ "crc32fast",
+ "libz-sys",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
+
+[[package]]
+name = "jobserver"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.121"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
+
+[[package]]
+name = "libz-sys"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
+dependencies = [
+ "cc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "num_threads"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0"
+dependencies = [
+ "libc",
+]
+
+[[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"
+checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "pbkdf2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
+dependencies = [
+ "digest",
+ "hmac",
+ "password-hash",
+ "sha2",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
+[[package]]
+name = "time"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
+dependencies = [
+ "itoa",
+ "libc",
+ "num_threads",
+ "time-macros",
+]
+
+[[package]]
+name = "time-macros"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
+
+[[package]]
+name = "typenum"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.10.2+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "zip"
+version = "0.6.3"
+dependencies = [
+ "aes",
+ "bencher",
+ "byteorder",
+ "bzip2",
+ "constant_time_eq",
+ "crc32fast",
+ "crossbeam-utils",
+ "flate2",
+ "getrandom",
+ "hmac",
+ "pbkdf2",
+ "sha1",
+ "time",
+ "walkdir",
+ "zstd",
+]
+
+[[package]]
+name = "zstd"
+version = "0.11.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "5.0.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.1+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b"
+dependencies = [
+ "cc",
+ "libc",
+]
diff --git a/Cargo.toml b/Cargo.toml
index fe1a031..7480ca9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,16 +12,30 @@
[package]
edition = "2018"
name = "zip"
-version = "0.6.2"
-authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>", "Marli Frost <marli@frost.red>", "Ryan Levick <ryan.levick@gmail.com>"]
-description = "Library to support the reading and writing of zip files.\n"
-keywords = ["zip", "archive"]
+version = "0.6.3"
+authors = [
+ "Mathijs van de Nes <git@mathijs.vd-nes.nl>",
+ "Marli Frost <marli@frost.red>",
+ "Ryan Levick <ryan.levick@gmail.com>",
+]
+description = """
+Library to support the reading and writing of zip files.
+"""
+keywords = [
+ "zip",
+ "archive",
+]
license = "MIT"
repository = "https://github.com/zip-rs/zip.git"
[[bench]]
name = "read_entry"
harness = false
+
+[[bench]]
+name = "read_metadata"
+harness = false
+
[dependencies.aes]
version = "0.7.5"
optional = true
@@ -41,7 +55,7 @@ optional = true
version = "1.3.2"
[dependencies.flate2]
-version = "1.0.22"
+version = "1.0.23"
optional = true
default-features = false
@@ -51,7 +65,7 @@ features = ["reset"]
optional = true
[dependencies.pbkdf2]
-version = "0.10.1"
+version = "0.11.0"
optional = true
[dependencies.sha1]
@@ -60,12 +74,16 @@ optional = true
[dependencies.time]
version = "0.3.7"
-features = ["formatting", "macros"]
+features = [
+ "formatting",
+ "macros",
+]
optional = true
[dependencies.zstd]
-version = "0.10.0"
+version = "0.11.0"
optional = true
+
[dev-dependencies.bencher]
version = "0.1.5"
@@ -76,11 +94,24 @@ version = "0.2.5"
version = "2.3.2"
[features]
-aes-crypto = ["aes", "constant_time_eq", "hmac", "pbkdf2", "sha1"]
-default = ["aes-crypto", "bzip2", "deflate", "time", "zstd"]
+aes-crypto = [
+ "aes",
+ "constant_time_eq",
+ "hmac",
+ "pbkdf2",
+ "sha1",
+]
+default = [
+ "aes-crypto",
+ "bzip2",
+ "deflate",
+ "time",
+ "zstd",
+]
deflate = ["flate2/rust_backend"]
deflate-miniz = ["flate2/default"]
deflate-zlib = ["flate2/zlib"]
unreserved = []
+
[target."cfg(any(all(target_arch = \"arm\", target_pointer_width = \"32\"), target_arch = \"mips\", target_arch = \"powerpc\"))".dependencies.crossbeam-utils]
version = "0.8.8"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index cc87821..a6996fc 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "zip"
-version = "0.6.2"
+version = "0.6.3"
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>", "Marli Frost <marli@frost.red>", "Ryan Levick <ryan.levick@gmail.com>"]
license = "MIT"
repository = "https://github.com/zip-rs/zip.git"
@@ -16,12 +16,12 @@ byteorder = "1.4.3"
bzip2 = { version = "0.4.3", optional = true }
constant_time_eq = { version = "0.1.5", optional = true }
crc32fast = "1.3.2"
-flate2 = { version = "1.0.22", default-features = false, optional = true }
+flate2 = { version = "1.0.23", default-features = false, optional = true }
hmac = { version = "0.12.1", optional = true, features = ["reset"] }
-pbkdf2 = {version = "0.10.1", optional = true }
+pbkdf2 = {version = "0.11.0", optional = true }
sha1 = {version = "0.10.1", optional = true }
time = { version = "0.3.7", features = ["formatting", "macros" ], optional = true }
-zstd = { version = "0.10.0", optional = true }
+zstd = { version = "0.11.0", optional = true }
[target.'cfg(any(all(target_arch = "arm", target_pointer_width = "32"), target_arch = "mips", target_arch = "powerpc"))'.dependencies]
crossbeam-utils = "0.8.8"
@@ -42,3 +42,7 @@ default = ["aes-crypto", "bzip2", "deflate", "time", "zstd"]
[[bench]]
name = "read_entry"
harness = false
+
+[[bench]]
+name = "read_metadata"
+harness = false
diff --git a/METADATA b/METADATA
index c6e83c0..209aab1 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/zip
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "zip"
description: "Library to support the reading and writing of zip files."
third_party {
@@ -7,13 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/zip/zip-0.6.2.crate"
+ value: "https://static.crates.io/crates/zip/zip-0.6.3.crate"
}
- version: "0.6.2"
+ version: "0.6.3"
license_type: NOTICE
last_upgrade_date {
year: 2022
- month: 4
- day: 13
+ month: 12
+ day: 19
}
}
diff --git a/README.md b/README.md
index 7db31d4..9b3c059 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ zip-rs
[![Crates.io version](https://img.shields.io/crates/v/zip.svg)](https://crates.io/crates/zip)
[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/rQ7H9cSsF4)
-[Documentation](https://docs.rs/zip/0.6.2/zip/)
+[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.
@@ -35,14 +35,14 @@ With all default features:
```toml
[dependencies]
-zip = "0.6.2"
+zip = "0.6.3"
```
Without the default features:
```toml
[dependencies]
-zip = { version = "0.6.2", default-features = false }
+zip = { version = "0.6.3", default-features = false }
```
The features available are:
@@ -58,7 +58,7 @@ All of these are enabled by default.
MSRV
----
-Our current Minimum Supported Rust Version is **1.54.0**. When adding features,
+Our current Minimum Supported Rust Version is **1.59.0**. When adding features,
we will follow these guidelines:
- We will always support the latest four minor Rust versions. This gives you a 6
@@ -75,3 +75,24 @@ See the [examples directory](examples) for:
* How to extract a zip file.
* How to extract a single file from a zip.
* How to read a zip from the standard input.
+
+Fuzzing
+-------
+
+Fuzzing support is through [cargo fuzz](https://github.com/rust-fuzz/cargo-fuzz). To install cargo fuzz:
+
+```bash
+cargo install cargo-fuzz
+```
+
+To list fuzz targets:
+
+```bash
+cargo +nightly fuzz list
+```
+
+To start fuzzing zip extraction:
+
+```bash
+cargo +nightly fuzz run fuzz_read
+```
diff --git a/benches/read_metadata.rs b/benches/read_metadata.rs
new file mode 100644
index 0000000..51f1f69
--- /dev/null
+++ b/benches/read_metadata.rs
@@ -0,0 +1,41 @@
+use bencher::{benchmark_group, benchmark_main};
+
+use std::io::{Cursor, Write};
+
+use bencher::Bencher;
+use zip::{ZipArchive, ZipWriter};
+
+const FILE_COUNT: usize = 15_000;
+const FILE_SIZE: usize = 1024;
+
+fn generate_random_archive(count_files: usize, file_size: usize) -> Vec<u8> {
+ let data = Vec::new();
+ let mut writer = ZipWriter::new(Cursor::new(data));
+ let options =
+ zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);
+
+ let bytes = vec![0u8; file_size];
+
+ for i in 0..count_files {
+ let name = format!(
+ "file_deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef_{}.dat",
+ i
+ );
+ writer.start_file(name, options).unwrap();
+ writer.write_all(&bytes).unwrap();
+ }
+
+ writer.finish().unwrap().into_inner()
+}
+
+fn read_metadata(bench: &mut Bencher) {
+ let bytes = generate_random_archive(FILE_COUNT, FILE_SIZE);
+
+ bench.iter(|| {
+ let archive = ZipArchive::new(Cursor::new(bytes.as_slice())).unwrap();
+ archive.len()
+ });
+}
+
+benchmark_group!(benches, read_metadata);
+benchmark_main!(benches);
diff --git a/src/read.rs b/src/read.rs
index c619f24..728ddf5 100644
--- a/src/read.rs
+++ b/src/read.rs
@@ -408,8 +408,16 @@ impl<R: Read + io::Seek> ZipArchive<R> {
let (archive_offset, directory_start, number_of_files) =
Self::get_directory_counts(&mut reader, &footer, cde_start_pos)?;
- let mut files = Vec::new();
- let mut names_map = HashMap::new();
+ // If the parsed number of files is greater than the offset then
+ // something fishy is going on and we shouldn't trust number_of_files.
+ let file_capacity = if number_of_files > cde_start_pos as usize {
+ 0
+ } else {
+ number_of_files
+ };
+
+ let mut files = Vec::with_capacity(file_capacity);
+ let mut names_map = HashMap::with_capacity(file_capacity);
if reader.seek(io::SeekFrom::Start(directory_start)).is_err() {
return Err(ZipError::InvalidArchive(
@@ -639,7 +647,7 @@ pub(crate) fn central_header_to_zip_file<R: Read + io::Seek>(
reader: &mut R,
archive_offset: u64,
) -> ZipResult<ZipFileData> {
- let central_header_start = reader.seek(io::SeekFrom::Current(0))?;
+ let central_header_start = reader.stream_position()?;
// Parse central header
let signature = reader.read_u32::<LittleEndian>()?;
if signature != spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE {
@@ -949,7 +957,7 @@ impl<'a> ZipFile<'a> {
match self.data.system {
System::Unix => Some(self.data.external_attributes >> 16),
System::Dos => {
- // Interpret MSDOS directory bit
+ // Interpret MS-DOS directory bit
let mut mode = if 0x10 == (self.data.external_attributes & 0x10) {
ffi::S_IFDIR | 0o0775
} else {
@@ -1267,4 +1275,36 @@ mod test {
);
}
}
+
+ /// 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() {
+ use super::ZipArchive;
+ use std::io;
+
+ let mut v = Vec::new();
+ v.extend_from_slice(include_bytes!(
+ "../tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip"
+ ));
+ let reader = ZipArchive::new(io::Cursor::new(v));
+ assert!(reader.is_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() {
+ use super::ZipArchive;
+ use std::io;
+
+ let mut v = Vec::new();
+ v.extend_from_slice(include_bytes!(
+ "../tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip"
+ ));
+ let reader = ZipArchive::new(io::Cursor::new(v));
+ assert!(reader.is_err());
+ }
}
diff --git a/src/write.rs b/src/write.rs
index 551b4e3..61ce378 100644
--- a/src/write.rs
+++ b/src/write.rs
@@ -174,7 +174,11 @@ impl FileOptions {
///
/// The format is represented with unix-style permissions.
/// The default is `0o644`, which represents `rw-r--r--` for files,
- /// and `0o755`, which represents `rwxr-xr-x` for directories
+ /// and `0o755`, which represents `rwxr-xr-x` for directories.
+ ///
+ /// This method only preserves the file permissions bits (via a `& 0o777`) and discards
+ /// higher file mode bits. So it cannot be used to denote an entry as a directory,
+ /// symlink, or other special file type.
#[must_use]
pub fn unix_permissions(mut self, mode: u32) -> FileOptions {
self.permissions = Some(mode & 0o777);
@@ -348,7 +352,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
{
let writer = self.inner.get_plain();
- let header_start = writer.seek(io::SeekFrom::Current(0))?;
+ let header_start = writer.stream_position()?;
let permissions = options.permissions.unwrap_or(0o100644);
let mut file = ZipFileData {
@@ -375,7 +379,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
};
write_local_file_header(writer, &file)?;
- let header_end = writer.seek(io::SeekFrom::Current(0))?;
+ let header_end = writer.stream_position()?;
self.stats.start = header_end;
*file.data_start.get_mut() = header_end;
@@ -404,7 +408,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
file.crc32 = self.stats.hasher.clone().finalize();
file.uncompressed_size = self.stats.bytes_written;
- let file_end = writer.seek(io::SeekFrom::Current(0))?;
+ let file_end = writer.stream_position()?;
file.compressed_size = file_end - self.stats.start;
update_local_file_header(writer, file)?;
@@ -723,7 +727,7 @@ impl<W: Write + io::Seek> ZipWriter<W> {
/// Add a directory entry, taking a Path as argument.
///
- /// This function ensures that the '/' path seperator is used. It also ignores all non 'Normal'
+ /// This function ensures that the '/' path separator is used. It also ignores all non 'Normal'
/// Components, such as a starting '/' or '..' and '.'.
#[deprecated(
since = "0.5.7",
@@ -747,17 +751,55 @@ impl<W: Write + io::Seek> ZipWriter<W> {
Ok(inner.unwrap())
}
+ /// Add a symlink entry.
+ ///
+ /// The zip archive will contain an entry for path `name` which is a symlink to `target`.
+ ///
+ /// No validation or normalization of the paths is performed. For best results,
+ /// callers should normalize `\` to `/` and ensure symlinks are relative to other
+ /// paths within the zip archive.
+ ///
+ /// WARNING: not all zip implementations preserve symlinks on extract. Some zip
+ /// implementations may materialize a symlink as a regular file, possibly with the
+ /// content incorrectly set to the symlink target. For maximum portability, consider
+ /// storing a regular file instead.
+ pub fn add_symlink<N, T>(
+ &mut self,
+ name: N,
+ target: T,
+ mut options: FileOptions,
+ ) -> ZipResult<()>
+ where
+ N: Into<String>,
+ T: Into<String>,
+ {
+ if options.permissions.is_none() {
+ options.permissions = Some(0o777);
+ }
+ *options.permissions.as_mut().unwrap() |= 0o120000;
+ // The symlink target is stored as file content. And compressing the target path
+ // likely wastes space. So always store.
+ options.compression_method = CompressionMethod::Stored;
+
+ self.start_entry(name, options, None)?;
+ self.writing_to_file = true;
+ self.write_all(target.into().as_bytes())?;
+ self.writing_to_file = false;
+
+ Ok(())
+ }
+
fn finalize(&mut self) -> ZipResult<()> {
self.finish_file()?;
{
let writer = self.inner.get_plain();
- let central_start = writer.seek(io::SeekFrom::Current(0))?;
+ let central_start = writer.stream_position()?;
for file in self.files.iter() {
write_central_directory_header(writer, file)?;
}
- let central_size = writer.seek(io::SeekFrom::Current(0))? - central_start;
+ let central_size = writer.stream_position()? - central_start;
if self.files.len() > spec::ZIP64_ENTRY_THR
|| central_size.max(central_start) > spec::ZIP64_BYTES_THR
@@ -1286,6 +1328,13 @@ mod test {
}
#[test]
+ fn unix_permissions_bitmask() {
+ // unix_permissions() throws away upper bits.
+ let options = FileOptions::default().unix_permissions(0o120777);
+ assert_eq!(options.permissions, Some(0o777));
+ }
+
+ #[test]
fn write_zip_dir() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
writer
@@ -1314,6 +1363,67 @@ mod test {
}
#[test]
+ fn write_symlink_simple() {
+ let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
+ writer
+ .add_symlink(
+ "name",
+ "target",
+ FileOptions::default().last_modified_time(
+ DateTime::from_date_and_time(2018, 8, 15, 20, 45, 6).unwrap(),
+ ),
+ )
+ .unwrap();
+ assert!(writer
+ .write(b"writing to a symlink is not allowed and will not write any data")
+ .is_err());
+ let result = writer.finish().unwrap();
+ assert_eq!(result.get_ref().len(), 112);
+ assert_eq!(
+ *result.get_ref(),
+ &[
+ 80u8, 75, 3, 4, 20, 0, 0, 0, 0, 0, 163, 165, 15, 77, 252, 47, 111, 70, 6, 0, 0, 0,
+ 6, 0, 0, 0, 4, 0, 0, 0, 110, 97, 109, 101, 116, 97, 114, 103, 101, 116, 80, 75, 1,
+ 2, 46, 3, 20, 0, 0, 0, 0, 0, 163, 165, 15, 77, 252, 47, 111, 70, 6, 0, 0, 0, 6, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 161, 0, 0, 0, 0, 110, 97, 109, 101,
+ 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 50, 0, 0, 0, 40, 0, 0, 0, 0, 0
+ ] as &[u8],
+ );
+ }
+
+ #[test]
+ fn write_symlink_wonky_paths() {
+ let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
+ writer
+ .add_symlink(
+ "directory\\link",
+ "/absolute/symlink\\with\\mixed/slashes",
+ FileOptions::default().last_modified_time(
+ DateTime::from_date_and_time(2018, 8, 15, 20, 45, 6).unwrap(),
+ ),
+ )
+ .unwrap();
+ assert!(writer
+ .write(b"writing to a symlink is not allowed and will not write any data")
+ .is_err());
+ let result = writer.finish().unwrap();
+ assert_eq!(result.get_ref().len(), 162);
+ assert_eq!(
+ *result.get_ref(),
+ &[
+ 80u8, 75, 3, 4, 20, 0, 0, 0, 0, 0, 163, 165, 15, 77, 95, 41, 81, 245, 36, 0, 0, 0,
+ 36, 0, 0, 0, 14, 0, 0, 0, 100, 105, 114, 101, 99, 116, 111, 114, 121, 92, 108, 105,
+ 110, 107, 47, 97, 98, 115, 111, 108, 117, 116, 101, 47, 115, 121, 109, 108, 105,
+ 110, 107, 92, 119, 105, 116, 104, 92, 109, 105, 120, 101, 100, 47, 115, 108, 97,
+ 115, 104, 101, 115, 80, 75, 1, 2, 46, 3, 20, 0, 0, 0, 0, 0, 163, 165, 15, 77, 95,
+ 41, 81, 245, 36, 0, 0, 0, 36, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
+ 161, 0, 0, 0, 0, 100, 105, 114, 101, 99, 116, 111, 114, 121, 92, 108, 105, 110,
+ 107, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 60, 0, 0, 0, 80, 0, 0, 0, 0, 0
+ ] as &[u8],
+ );
+ }
+
+ #[test]
fn write_mimetype_zip() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let options = FileOptions {
diff --git a/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip b/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip
new file mode 100644
index 0000000..a428ca7
--- /dev/null
+++ b/tests/data/invalid_cde_number_of_files_allocation_greater_offset.zip
Binary files differ
diff --git a/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip b/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip
new file mode 100644
index 0000000..2cc9007
--- /dev/null
+++ b/tests/data/invalid_cde_number_of_files_allocation_smaller_offset.zip
Binary files differ