Bug 1772965 - Update geckodriver to zip 0.6. r=webdriver-reviewers,whimboo

Differential Revision: https://phabricator.services.mozilla.com/D148465
This commit is contained in:
Mike Hommey 2022-06-07 09:27:44 +00:00
Родитель 57c2d48e4f
Коммит f2afd39ca6
59 изменённых файлов: 5024 добавлений и 2672 удалений

26
Cargo.lock сгенерированный
Просмотреть файл

@ -3455,16 +3455,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "msdos_time"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729"
dependencies = [
"time 0.1.43",
"winapi",
]
[[package]]
name = "murmurhash3"
version = "0.0.5"
@ -4046,12 +4036,6 @@ dependencies = [
"xml-rs",
]
[[package]]
name = "podio"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b18befed8bc2b61abc79a457295e7e838417326da1586050b919414073977f19"
[[package]]
name = "ppv-lite86"
version = "0.2.16"
@ -6125,12 +6109,12 @@ dependencies = [
[[package]]
name = "zip"
version = "0.4.2"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36b9e08fb518a65cf7e08a1e482573eb87a2f4f8c6619316612a3c1f162fe822"
checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d"
dependencies = [
"byteorder",
"crc32fast",
"crossbeam-utils 0.8.8",
"flate2",
"msdos_time",
"podio",
"time 0.1.43",
]

Просмотреть файл

@ -30,7 +30,7 @@ tempfile = "3"
url = "2.0"
uuid = { version = "0.8", features = ["v4"] }
webdriver = { path = "../webdriver", version="0.45.0" }
zip = { version = "0.4", default-features = false, features = ["deflate"] }
zip = { version = "0.6", default-features = false, features = ["deflate"] }
[dev-dependencies]
tempfile = "3"

Просмотреть файл

@ -1 +0,0 @@
{"files":{"Cargo.toml":"3faa730a95b1a21d63ca11b375e9e86793565a573db649df01562bb24a0b1b43","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"0241727cb9f7e4ab1ad206ff89ec1dc31034a69b146f076237e8c1b1534b6fe0","README.md":"11cdfba96992fcee089bdcad6682ba5357d8161304d35618ee76abad298ffba7","appveyor.yml":"266ca65d48f02c6a3ce1ba1c0772ef9afece737da03b3176e000b7c32a9ea748","script/doc-upload.cfg":"8cae598ef8592842fa8319b18d515e7a322296490cbdf909b29f5e042a95419e","src/lib.rs":"282e6beaef56932a3737e1b60e71ddfdf620d35a9cafdfaa1cc59b54f7d43009"},"package":"aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729"}

28
third_party/rust/msdos_time/Cargo.toml поставляемый
Просмотреть файл

@ -1,28 +0,0 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "msdos_time"
version = "0.1.6"
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"]
description = "Converts an MsDosDateTime (FAT time) to a Tm value\n"
documentation = "https://mvdnes.github.io/rust-docs/msdos_time/msdos_time/"
license = "MIT OR Apache-2.0"
repository = "https://github.com/mvdnes/msdos_time"
[lib]
name = "msdos_time"
[dependencies.time]
version = "0.1"
[target."cfg(windows)".dependencies.winapi]
version = "0.3"
features = ["winbase", "timezoneapi"]

202
third_party/rust/msdos_time/LICENSE-APACHE поставляемый
Просмотреть файл

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

19
third_party/rust/msdos_time/LICENSE-MIT поставляемый
Просмотреть файл

@ -1,19 +0,0 @@
Copyright (c) 2015 The msdos_time Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
third_party/rust/msdos_time/README.md поставляемый
Просмотреть файл

@ -1,25 +0,0 @@
# msdos_time
[![Build Status](https://travis-ci.org/mvdnes/msdos_time.svg?branch=master)](https://travis-ci.org/mvdnes/msdos_time)
[![Build status](https://ci.appveyor.com/api/projects/status/tf4jgk6wr66n17xa/branch/master?svg=true)](https://ci.appveyor.com/project/mvdnes/msdos-time/branch/master)
[![Crates.io](https://img.shields.io/crates/v/msdos_time.svg)](https://crates.io/crates/msdos_time)
[Documentation](https://mvdnes.github.io/rust-docs/msdos_time/msdos_time/)
Library to convert Fat time to a Tm struct in Rust.
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the Apache-2.0
license, shall be dual licensed as above, without any additional terms or
conditions.

39
third_party/rust/msdos_time/appveyor.yml поставляемый
Просмотреть файл

@ -1,39 +0,0 @@
environment:
matrix:
- RUST_INSTALL_TRIPLE: i686-pc-windows-gnu
RUST_CHANNEL: stable
- RUST_INSTALL_TRIPLE: x86_64-pc-windows-gnu
RUST_CHANNEL: stable
- RUST_INSTALL_TRIPLE: x86_64-pc-windows-msvc
RUST_CHANNEL: stable
matrix:
allow_failures:
- RUST_CHANNEL: nightly
install:
- ps: Start-FileDownload "http://static.rust-lang.org/dist/channel-rust-${env:RUST_CHANNEL}"
- ps: $env:RUST_INSTALLER = Select-String "${env:RUST_INSTALL_TRIPLE}.*exe" "channel-rust-${env:RUST_CHANNEL}" | select -exp line
- ps: Start-FileDownload "http://static.rust-lang.org/dist/${env:RUST_INSTALLER}"
- '%RUST_INSTALLER% /VERYSILENT /NORESTART /DIR="C:\Rust"'
- call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
- ps: $env:path = "C:\Rust\bin;" + $env:path
- ps: |
if ($env:RUST_INSTALL_TRIPLE -like "x86_64-*-gnu") {
Start-FileDownload "http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/5.1.0/threads-win32/seh/x86_64-5.1.0-release-win32-seh-rt_v4-rev0.7z/download" -FileName mingw64.7z
7z x -oC:\ mingw64.7z > $null
$env:path = "C:\mingw64\bin;" + $env:path
gcc --version
}
elseif ($env:RUST_INSTALL_TRIPLE -like "i686-*-gnu") {
$env:path = "C:\mingw\bin;" + $env:path
gcc --version
}
- rustc --version --verbose
- cargo --version
build: false
test_script:
- cargo build
- cargo test

Просмотреть файл

@ -1,3 +0,0 @@
PROJECT_NAME=msdos_time
DOCS_REPO=mvdnes/rust-docs.git
DOC_RUST_VERSION=stable

225
third_party/rust/msdos_time/src/lib.rs поставляемый
Просмотреть файл

@ -1,225 +0,0 @@
#![warn(missing_docs)]
//! This crate converts a `Tm` struct to an `MsDosDateTime` and vice-versa
//!
//! MsDosDateTime is based on a FAT datetime and is a compact representation of a date.
//! It is currently mostly used in zip files.
extern crate time;
#[cfg(windows)] extern crate winapi;
use std::io;
use time::Tm;
/// Struct representing the date and time part of an MsDos datetime
#[derive(Copy, Clone, Debug)]
pub struct MsDosDateTime {
/// Part representing the date
pub datepart: u16,
/// Part representing the time
pub timepart: u16,
}
impl MsDosDateTime {
/// Constructor of an MsDos datetime, from the raw representation
pub fn new(time: u16, date: u16) -> MsDosDateTime {
MsDosDateTime {
datepart: date,
timepart: time,
}
}
}
/// Trait to convert a time representation to and from a MsDosDateTime
pub trait TmMsDosExt : Sized {
/// Convert a value to MsDosDateTime
fn to_msdos(&self) -> Result<MsDosDateTime, io::Error>;
/// Construct a value from an MsDosDateTime
fn from_msdos(MsDosDateTime) -> Result<Self, io::Error>;
}
impl TmMsDosExt for Tm {
fn to_msdos(&self) -> Result<MsDosDateTime, io::Error> {
sys::tm_to_msdos(self)
}
fn from_msdos(ms: MsDosDateTime) -> Result<Self, io::Error> {
sys::msdos_to_tm(ms)
}
}
#[cfg(not(windows))]
mod sys {
use super::MsDosDateTime;
use time::{self, Tm};
use std::io;
pub fn msdos_to_tm(ms: MsDosDateTime) -> Result<Tm, io::Error> {
let seconds = (ms.timepart & 0b0000000000011111) << 1;
let minutes = (ms.timepart & 0b0000011111100000) >> 5;
let hours = (ms.timepart & 0b1111100000000000) >> 11;
let days = (ms.datepart & 0b0000000000011111) >> 0;
let months = (ms.datepart & 0b0000000111100000) >> 5;
let years = (ms.datepart & 0b1111111000000000) >> 9;
// Month range: Dos [1..12], Tm [0..11]
// Year zero: Dos 1980, Tm 1900
let tm = Tm {
tm_sec: seconds as i32,
tm_min: minutes as i32,
tm_hour: hours as i32,
tm_mday: days as i32,
tm_mon: months as i32 - 1,
tm_year: years as i32 + 80,
..time::empty_tm()
};
// Re-parse the possibly incorrect timestamp to get a correct one.
// This ensures every value will be in range
// TODO: Check if this will only panic on Windows, or also other platforms
Ok(time::at_utc(tm.to_timespec()))
}
pub fn tm_to_msdos(tm: &Tm) -> Result<MsDosDateTime, io::Error> {
let timepart = ((tm.tm_sec >> 1) | (tm.tm_min << 5) | (tm.tm_hour << 11)) as u16;
let datepart = (tm.tm_mday | ((tm.tm_mon + 1) << 5) | ((tm.tm_year - 80) << 9)) as u16;
Ok(MsDosDateTime { datepart: datepart, timepart: timepart })
}
}
#[cfg(windows)]
mod sys {
use super::MsDosDateTime;
use time::{self, Tm};
use winapi::shared::minwindef::{WORD, FILETIME};
use winapi::um::minwinbase::SYSTEMTIME;
use winapi::um::timezoneapi::{FileTimeToSystemTime, SystemTimeToFileTime};
use winapi::um::winbase::{DosDateTimeToFileTime, FileTimeToDosDateTime};
use std::io;
pub fn msdos_to_tm(ms: MsDosDateTime) -> Result<Tm, io::Error> {
let datepart: WORD = ms.datepart;
let timepart: WORD = ms.timepart;
let mut filetime: FILETIME = unsafe { ::std::mem::zeroed() };
let mut systemtime: SYSTEMTIME = unsafe { ::std::mem::zeroed() };
if unsafe { DosDateTimeToFileTime(datepart, timepart, &mut filetime) } == 0 {
return Err(io::Error::last_os_error());
}
if unsafe { FileTimeToSystemTime(&filetime, &mut systemtime) } == 0 {
return Err(io::Error::last_os_error());
}
Ok(Tm {
tm_sec: systemtime.wSecond as i32,
tm_min: systemtime.wMinute as i32,
tm_hour: systemtime.wHour as i32,
tm_mday: systemtime.wDay as i32,
tm_wday: systemtime.wDayOfWeek as i32,
tm_mon: (systemtime.wMonth - 1) as i32,
tm_year: (systemtime.wYear - 1900) as i32,
..time::empty_tm()
})
}
pub fn tm_to_msdos(tm: &Tm) -> Result<MsDosDateTime, io::Error> {
let systemtime = SYSTEMTIME {
wYear: (tm.tm_year + 1900) as WORD,
wMonth: (tm.tm_mon + 1) as WORD,
wDayOfWeek: tm.tm_wday as WORD,
wDay: tm.tm_mday as WORD,
wHour: tm.tm_hour as WORD,
wMinute: tm.tm_min as WORD,
wSecond: tm.tm_sec as WORD,
wMilliseconds: 0,
};
let mut filetime = unsafe { ::std::mem::zeroed() };
let mut datepart : WORD = 0;
let mut timepart : WORD = 0;
if unsafe { SystemTimeToFileTime(&systemtime, &mut filetime) } == 0 {
return Err(io::Error::last_os_error());
}
if unsafe { FileTimeToDosDateTime(&filetime, &mut datepart, &mut timepart) } == 0 {
return Err(io::Error::last_os_error());
}
Ok(MsDosDateTime { datepart: datepart, timepart: timepart })
}
}
#[cfg(test)]
mod test {
use super::*;
use time::{self, Tm};
fn check_date(input: Tm, day: i32, month: i32, year: i32) {
assert_eq!(input.tm_mday, day);
assert_eq!(input.tm_mon + 1, month);
assert_eq!(input.tm_year + 1900, year);
}
fn check_time(input: Tm, hour: i32, minute: i32, second: i32) {
assert_eq!(input.tm_hour, hour);
assert_eq!(input.tm_min, minute);
assert_eq!(input.tm_sec, second);
}
#[test]
fn dos_zero() {
// The 0 date is not a correct msdos date
// We assert here that it does not panic. What it will return is undefined.
let _ = Tm::from_msdos(MsDosDateTime::new(0, 0));
}
#[test]
fn dos_smallest() {
// This is the actual smallest date possible
let tm = Tm::from_msdos(MsDosDateTime::new(0, 0b100001)).unwrap();
check_date(tm, 1, 1, 1980);
check_time(tm, 0, 0, 0);
}
#[test]
fn dos_today() {
let tm = Tm::from_msdos(MsDosDateTime::new(0b01001_100000_10101, 0b0100011_0110_11110)).unwrap();
check_date(tm, 30, 6, 2015);
check_time(tm, 9, 32, 42);
}
#[test]
fn zero_dos() {
let tm = Tm {
tm_year: 80,
tm_mon: 0,
tm_mday: 1,
tm_hour: 0,
tm_min: 0,
tm_sec: 0,
..time::empty_tm()
};
let ms = tm.to_msdos().unwrap();
assert_eq!(ms.datepart, 0b100001);
assert_eq!(ms.timepart, 0);
}
#[test]
fn today_dos() {
let tm = Tm {
tm_year: 115,
tm_mon: 5,
tm_mday: 30,
tm_hour: 9,
tm_min: 32,
tm_sec: 42,
..time::empty_tm()
};
let ms = tm.to_msdos().unwrap();
assert_eq!(ms.datepart, 0b0100011_0110_11110);
assert_eq!(ms.timepart, 0b01001_100000_10101);
}
}

1
third_party/rust/podio/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +0,0 @@
{"files":{"Cargo.toml":"864dd81db21e85db5b74242b5f486b75bab2f5b9f666e6ee63e41d02520783f7","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"892ad0db8a971b86db947bae64542aa67d91cfae768b3ed3ea281c54844a4ae9","README.md":"4b66e3517754d9aabe44c17b224f1d1e72a6fb50507d49536e6825a3e4d0b347","appveyor.yml":"5940accb4ac2c4904459a7a600da6b8dca015653ba273eab7e87894df464d379","benches/benchmark.rs":"0adade342f2046c8d6f669097209f23b4d8a35c6b5dc2c3687addf2f4444aa40","script/doc-upload.cfg":"273e9501d95820583705e9f4c4f84afefba4fd227223fc3d165dfb1aba91c5d1","src/lib.rs":"32efe5d0a248a707c68ca7084d3855c6d918fc12d7f49b1fec56002116ecb735","tests/bytes.rs":"1cb1979745f35086a785df207f3b0f660cf6720e123c3e0042fb924d5795aa37","tests/io.rs":"19e4699082d0a0432dfa23bda2a54ed426d23bf7f07a579ba4305a1926d952ec"},"package":"b18befed8bc2b61abc79a457295e7e838417326da1586050b919414073977f19"}

21
third_party/rust/podio/Cargo.toml поставляемый
Просмотреть файл

@ -1,21 +0,0 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "podio"
version = "0.1.7"
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"]
description = "Additional trait for Read and Write to read and write Plain Old Data\n"
documentation = "http://mvdnes.github.io/rust-docs/podio/podio/index.html"
keywords = ["byte", "byteorder", "io"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/mvdnes/podio.git"

202
third_party/rust/podio/LICENSE-APACHE поставляемый
Просмотреть файл

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

19
third_party/rust/podio/LICENSE-MIT поставляемый
Просмотреть файл

@ -1,19 +0,0 @@
Copyright (c) 2015 The podio Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

56
third_party/rust/podio/README.md поставляемый
Просмотреть файл

@ -1,56 +0,0 @@
podio
=====
[![Build Status](https://travis-ci.org/mvdnes/podio.svg?branch=master)](https://travis-ci.org/mvdnes/podio)
[![Build status](https://ci.appveyor.com/api/projects/status/hjc3icfjob7mocc9/branch/master?svg=true)](https://ci.appveyor.com/project/mvdnes/podio/branch/master)
[![Crates.io version](https://img.shields.io/crates/v/podio.svg)](https://crates.io/crates/podio)
[Documentation](http://mvdnes.github.io/rust-docs/podio/podio/index.html)
Implementation for reading and writing POD (plain old data) values in Rust. The name stands for POD I/O.
Keywords: byte, be, le, big-endian, little-endian
Usage
-----
Include the following code:
```toml
[dependencies]
podio = "0.1"
```
Example
-------
```rust
extern crate podio;
use podio::{ReadPodExt, BigEndian};
fn main() {
let slice: &[u8] = &[0x10, 0x20, 0x30, 0x40];
let mut reader = std::io::Cursor::new(slice);
let value = reader.read_u32::<BigEndian>().unwrap();
assert_eq!(value, 0x10203040);
}
```
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the Apache-2.0
license, shall be dual licensed as above, without any additional terms or
conditions.

43
third_party/rust/podio/appveyor.yml поставляемый
Просмотреть файл

@ -1,43 +0,0 @@
# Appveyor configuration template for Rust using rustup for Rust installation
# https://github.com/starkat99/appveyor-rust
os: Visual Studio 2015
environment:
matrix:
# Stable 64-bit MSVC
- channel: stable
target: x86_64-pc-windows-msvc
# Stable 32-bit MSVC
- channel: stable
target: i686-pc-windows-msvc
# Stable 64-bit GNU
- channel: stable
target: x86_64-pc-windows-gnu
# Stable 32-bit GNU
- channel: stable
target: i686-pc-windows-gnu
install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init -yv --default-toolchain %channel% --default-host %target%
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
- ps: |
if ($env:target -like "*-gnu" -And $env:target -like "x86_64-*") {
Start-FileDownload "http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/5.1.0/threads-win32/seh/x86_64-5.1.0-release-win32-seh-rt_v4-rev0.7z/download" -FileName mingw64.7z
7z x -oC:\ mingw64.7z > $null
$env:path = "C:\mingw64\bin;" + $env:path
gcc --version
}
elseif ($env:target -like "*-gnu") {
$env:path = "C:\mingw\bin;" + $env:path
gcc --version
}
- rustc -vV
- cargo -vV
build: false
test_script:
- cargo test

49
third_party/rust/podio/benches/benchmark.rs поставляемый
Просмотреть файл

@ -1,49 +0,0 @@
// bench.rs
#![feature(test)]
extern crate podio;
extern crate test;
use test::Bencher;
use podio::{Endianness, BigEndian, LittleEndian, WritePodExt, ReadPodExt};
// bench: find the `BENCH_SIZE` first terms of the fibonacci sequence
const BENCH_SIZE: usize = 2000;
#[bench]
fn write_u64_be(b: &mut Bencher) {
write_u64::<BigEndian>(b);
}
#[bench]
fn write_u64_le(b: &mut Bencher) {
write_u64::<LittleEndian>(b);
}
fn write_u64<T: Endianness>(b: &mut Bencher) {
b.iter(|| {
let mut writer : &mut[u8] = &mut [0; BENCH_SIZE * 8];
for _ in 0..BENCH_SIZE {
writer.write_u64::<T>(0x012345678u64).unwrap();
}
})
}
#[bench]
fn read_u64_be(b: &mut Bencher) {
read_u64::<BigEndian>(b);
}
#[bench]
fn read_u64_le(b: &mut Bencher) {
read_u64::<LittleEndian>(b);
}
fn read_u64<T: Endianness>(b: &mut Bencher) {
b.iter(|| {
let mut reader : &[u8] = &[0; BENCH_SIZE * 8];
for _ in 0..BENCH_SIZE {
reader.read_u64::<T>().unwrap();
}
})
}

Просмотреть файл

@ -1,3 +0,0 @@
PROJECT_NAME=podio
DOCS_REPO=mvdnes/rust-docs.git
DOC_RUST_VERSION=stable

364
third_party/rust/podio/src/lib.rs поставляемый
Просмотреть файл

@ -1,364 +0,0 @@
//! Additional methods for Read and Write
//!
//! The additional methods implemented allow reading and writing integers and floats
//! in the specified endianness.
//!
//! # Usage
//!
//! Basically, you need to `use` the trait WritePodExt or ReadPodExt.
//!
//! # Examples
//!
//! ## Reading
//!
//! To read some value from a reader, import ReadPodExt and the needed endianness.
//!
//! ```
//! use podio::{ReadPodExt, BigEndian};
//!
//! let slice: &[u8] = &[0x10, 0x20, 0x30, 0x40];
//! let mut reader = std::io::Cursor::new(slice);
//!
//! let value = reader.read_u32::<BigEndian>().unwrap();
//!
//! assert_eq!(value, 0x10203040);
//! ```
//!
//! ## Writing
//!
//! For writing, you need to import the trait WritePodExt.
//!
//! ```
//! use podio::{WritePodExt, LittleEndian};
//!
//! let slice: &mut [u8] = &mut [0; 2];
//! let mut writer = std::io::Cursor::new(slice);
//!
//! writer.write_u16::<LittleEndian>(0x8802).unwrap();
//!
//! assert_eq!(writer.into_inner(), &[0x02, 0x88]);
//! ```
//!
//! ## Read exact
//!
//! One additional method, not really dealing with POD, is `read_exact`.
//!
//! ```
//! use podio::ReadPodExt;
//!
//! let slice: &[u8] = &[0, 1, 2, 3];
//! let mut reader = std::io::Cursor::new(slice);
//!
//! assert_eq!(reader.read_exact(1).unwrap(), [0]);
//! assert_eq!(reader.read_exact(2).unwrap(), [1,2]);
//! assert_eq!(reader.read_exact(0).unwrap(), []);
//! assert_eq!(reader.read_exact(1).unwrap(), [3]);
//! assert!(reader.read_exact(1).is_err());
#![warn(missing_docs)]
use std::io;
use std::io::prelude::*;
/// Little endian. The number `0xABCD` is stored `[0xCD, 0xAB]`
pub enum LittleEndian {}
/// Big endian. The number `0xABCD` is stored `[0xAB, 0xCD]`
pub enum BigEndian {}
/// Trait implementing conversion methods for a specific endianness
pub trait Endianness {
/// Converts a value from the platform type to the specified endianness
fn int_to_target<T: EndianConvert>(val: T) -> T;
/// Converts a value from the sepcified endianness to the platform type
fn int_from_target<T: EndianConvert>(val: T) -> T;
}
/// Generic trait for endian conversions on integers
pub trait EndianConvert {
/// Convert self to a big-endian value
fn to_be(self) -> Self;
/// Convert self to a little-endian value
fn to_le(self) -> Self;
/// Convert a big-endian value to the target endianness
fn from_be(x: Self) -> Self;
/// Convert a little-endian value to the target endiannes
fn from_le(x: Self) -> Self;
}
/// Additional write methods for a io::Write
pub trait WritePodExt {
/// Write a u64
fn write_u64<T: Endianness>(&mut self, u64) -> io::Result<()>;
/// Write a u32
fn write_u32<T: Endianness>(&mut self, u32) -> io::Result<()>;
/// Write a u16
fn write_u16<T: Endianness>(&mut self, u16) -> io::Result<()>;
/// Write a u8
fn write_u8(&mut self, u8) -> io::Result<()>;
/// Write a i64
fn write_i64<T: Endianness>(&mut self, i64) -> io::Result<()>;
/// Write a i32
fn write_i32<T: Endianness>(&mut self, i32) -> io::Result<()>;
/// Write a i16
fn write_i16<T: Endianness>(&mut self, i16) -> io::Result<()>;
/// Write a i8
fn write_i8(&mut self, i8) -> io::Result<()>;
/// Write a f32
fn write_f32<T: Endianness>(&mut self, f32) -> io::Result<()>;
/// Write a f64
fn write_f64<T: Endianness>(&mut self, f64) -> io::Result<()>;
}
/// Additional read methods for a io::Read
pub trait ReadPodExt {
/// Read a u64
fn read_u64<T: Endianness>(&mut self) -> io::Result<u64>;
/// Read a u32
fn read_u32<T: Endianness>(&mut self) -> io::Result<u32>;
/// Read a u16
fn read_u16<T: Endianness>(&mut self) -> io::Result<u16>;
/// Read a u8
fn read_u8(&mut self) -> io::Result<u8>;
/// Read a i64
fn read_i64<T: Endianness>(&mut self) -> io::Result<i64>;
/// Read a i32
fn read_i32<T: Endianness>(&mut self) -> io::Result<i32>;
/// Read a i16
fn read_i16<T: Endianness>(&mut self) -> io::Result<i16>;
/// Read a i8
fn read_i8(&mut self) -> io::Result<i8>;
/// Read a f32
fn read_f32<T: Endianness>(&mut self) -> io::Result<f32>;
/// Read a f64
fn read_f64<T: Endianness>(&mut self) -> io::Result<f64>;
/// Read a specific number of bytes
fn read_exact(&mut self, usize) -> io::Result<Vec<u8>>;
}
impl Endianness for LittleEndian {
#[inline]
fn int_to_target<T: EndianConvert>(val: T) -> T {
val.to_le()
}
#[inline]
fn int_from_target<T: EndianConvert>(val: T) -> T {
<T as EndianConvert>::from_le(val)
}
}
impl Endianness for BigEndian {
#[inline]
fn int_to_target<T: EndianConvert>(val: T) -> T {
val.to_be()
}
#[inline]
fn int_from_target<T: EndianConvert>(val: T) -> T {
<T as EndianConvert>::from_be(val)
}
}
macro_rules! impl_platform_convert {
($T:ty) => {
impl EndianConvert for $T {
#[inline]
fn to_be(self) -> $T {
self.to_be()
}
#[inline]
fn to_le(self) -> $T {
self.to_le()
}
#[inline]
fn from_be(x: $T) -> $T {
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
}
#[inline]
fn from_le(x: $T) -> $T {
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
}
}
};
}
impl_platform_convert!(u8);
impl_platform_convert!(u16);
impl_platform_convert!(u32);
impl_platform_convert!(u64);
#[cfg(target_endian = "little")]
macro_rules! val_to_buf {
($val:ident, $T:expr) => {
{
let mut buf = [0; $T];
for i in 0..buf.len() {
buf[i] = ($val >> (i * 8)) as u8;
}
buf
}
};
}
#[cfg(target_endian = "big")]
macro_rules! val_to_buf {
($val:ident, $T:expr) => {
{
let mut buf = [0; $T];
for i in 0..buf.len() {
buf[buf.len() - 1 - i] = ($val >> (i * 8)) as u8;
}
buf
}
};
}
impl<W: Write> WritePodExt for W {
fn write_u64<T: Endianness>(&mut self, val: u64) -> io::Result<()> {
let tval = <T as Endianness>::int_to_target(val);
let buf = val_to_buf!(tval, 8);
self.write_all(&buf)
}
fn write_u32<T: Endianness>(&mut self, val: u32) -> io::Result<()> {
let tval = <T as Endianness>::int_to_target(val);
let buf = val_to_buf!(tval, 4);
self.write_all(&buf)
}
fn write_u16<T: Endianness>(&mut self, val: u16) -> io::Result<()> {
let tval = <T as Endianness>::int_to_target(val);
let buf = val_to_buf!(tval, 2);
self.write_all(&buf)
}
fn write_u8(&mut self, val: u8) -> io::Result<()> {
self.write_all(&[val])
}
fn write_i64<T: Endianness>(&mut self, val: i64) -> io::Result<()> {
self.write_u64::<T>(val as u64)
}
fn write_i32<T: Endianness>(&mut self, val: i32) -> io::Result<()> {
self.write_u32::<T>(val as u32)
}
fn write_i16<T: Endianness>(&mut self, val: i16) -> io::Result<()> {
self.write_u16::<T>(val as u16)
}
fn write_i8(&mut self, val: i8) -> io::Result<()> {
self.write_u8(val as u8)
}
fn write_f32<T: Endianness>(&mut self, val: f32) -> io::Result<()> {
let tval: u32 = val.to_bits();
self.write_u32::<T>(tval)
}
fn write_f64<T: Endianness>(&mut self, val: f64) -> io::Result<()> {
let tval: u64 = val.to_bits();
self.write_u64::<T>(tval)
}
}
#[inline]
fn fill_buf<R: Read>(reader: &mut R, buf: &mut [u8]) -> io::Result<()> {
let mut idx = 0;
while idx != buf.len() {
match reader.read(&mut buf[idx..]) {
Ok(0) => return Err(io::Error::new(io::ErrorKind::Other, "Could not read enough bytes")),
Ok(v) => { idx += v; }
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
#[cfg(target_endian = "little")]
macro_rules! buf_to_val {
($buf:ident, $T:ty) => {
{
let mut val: $T = 0;
for i in 0..$buf.len() {
val |= ($buf[i] as $T) << (i * 8);
}
val
}
};
}
#[cfg(target_endian = "big")]
macro_rules! buf_to_val {
($buf:ident, $T:ty) => {
{
let mut val: $T = 0;
for i in 0..$buf.len() {
val |= ($buf[$buf.len() - 1 - i] as $T) << (i * 8);
}
val
}
};
}
impl<R: Read> ReadPodExt for R {
fn read_u64<T: Endianness>(&mut self) -> io::Result<u64> {
let buf = &mut [0u8; 8];
try!(fill_buf(self, buf));
let tval = buf_to_val!(buf, u64);
Ok(<T as Endianness>::int_from_target(tval))
}
fn read_u32<T: Endianness>(&mut self) -> io::Result<u32> {
let buf = &mut [0u8; 4];
try!(fill_buf(self, buf));
let tval = buf_to_val!(buf, u32);
Ok(<T as Endianness>::int_from_target(tval))
}
fn read_u16<T: Endianness>(&mut self) -> io::Result<u16> {
let buf = &mut [0u8; 2];
try!(fill_buf(self, buf));
let tval = buf_to_val!(buf, u16);
Ok(<T as Endianness>::int_from_target(tval))
}
fn read_u8(&mut self) -> io::Result<u8> {
let buf = &mut [0u8; 1];
try!(fill_buf(self, buf));
Ok(buf[0])
}
fn read_i64<T: Endianness>(&mut self) -> io::Result<i64> {
self.read_u64::<T>().map(|v| v as i64)
}
fn read_i32<T: Endianness>(&mut self) -> io::Result<i32> {
self.read_u32::<T>().map(|v| v as i32)
}
fn read_i16<T: Endianness>(&mut self) -> io::Result<i16> {
self.read_u16::<T>().map(|v| v as i16)
}
fn read_i8(&mut self) -> io::Result<i8> {
self.read_u8().map(|v| v as i8)
}
fn read_f64<T: Endianness>(&mut self) -> io::Result<f64> {
self.read_u64::<T>().map(|v| f64::from_bits(v))
}
fn read_f32<T: Endianness>(&mut self) -> io::Result<f32> {
self.read_u32::<T>().map(|v| f32::from_bits(v))
}
fn read_exact(&mut self, len: usize) -> io::Result<Vec<u8>> {
let mut res = vec![0; len];
try!(fill_buf(self, &mut res));
Ok(res)
}
}

139
third_party/rust/podio/tests/bytes.rs поставляемый
Просмотреть файл

@ -1,139 +0,0 @@
extern crate podio;
use std::io;
use podio::{LittleEndian, BigEndian};
use podio::{ReadPodExt, WritePodExt};
#[test]
fn write_be() {
let buf: &mut [u8] = &mut [0u8; 8];
let mut writer = io::Cursor::new(buf);
writer.set_position(0);
writer.write_u64::<BigEndian>(0x01_23_45_67_89_ab_cd_ef).unwrap();
assert_eq!(&writer.get_ref()[0..8], &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
writer.set_position(0);
writer.write_u32::<BigEndian>(0x01_23_45_67).unwrap();
assert_eq!(&writer.get_ref()[0..4], &[0x01, 0x23, 0x45, 0x67]);
writer.set_position(0);
writer.write_u16::<BigEndian>(0x01_23).unwrap();
assert_eq!(&writer.get_ref()[0..2], &[0x01, 0x23]);
}
#[test]
fn write_le() {
let buf: &mut [u8] = &mut [0u8; 8];
let mut writer = io::Cursor::new(buf);
writer.set_position(0);
writer.write_u64::<LittleEndian>(0x01_23_45_67_89_ab_cd_ef).unwrap();
assert_eq!(&writer.get_ref()[0..8], &[0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01]);
writer.set_position(0);
writer.write_u32::<LittleEndian>(0x01_23_45_67).unwrap();
assert_eq!(&writer.get_ref()[0..4], &[0x67, 0x45, 0x23, 0x01]);
writer.set_position(0);
writer.write_u16::<LittleEndian>(0x01_23).unwrap();
assert_eq!(&writer.get_ref()[0..2], &[0x23, 0x01]);
}
#[test]
fn write_octet() {
let buf: &mut [u8] = &mut [0u8; 8];
let mut writer = io::Cursor::new(buf);
writer.set_position(0);
writer.write_u8(0x01).unwrap();
assert_eq!(&writer.get_ref()[0..1], &[0x01]);
}
#[test]
fn write_float() {
let buf: &mut [u8] = &mut [0u8; 8];
let mut writer = io::Cursor::new(buf);
writer.set_position(0);
writer.write_f32::<LittleEndian>(10.12f32).unwrap();
assert_eq!(&writer.get_ref()[0..4], &[0x85, 0xEB, 0x21, 0x41]);
writer.set_position(0);
writer.write_f32::<BigEndian>(10.12f32).unwrap();
assert_eq!(&writer.get_ref()[0..4], &[0x41, 0x21, 0xEB, 0x85]);
writer.set_position(0);
writer.write_f64::<LittleEndian>(10.12f64).unwrap();
assert_eq!(&writer.get_ref()[0..8], &[0x3D, 0x0A, 0xD7, 0xA3, 0x70, 0x3D, 0x24, 0x40]);
writer.set_position(0);
writer.write_f64::<BigEndian>(10.12f64).unwrap();
assert_eq!(&writer.get_ref()[0..8], &[0x40, 0x24, 0x3D, 0x70, 0xA3, 0xD7, 0x0A, 0x3D]);
}
#[test]
fn read_be() {
let buf: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
let mut reader = io::Cursor::new(buf);
reader.set_position(0);
assert_eq!(reader.read_u64::<BigEndian>().unwrap(), 0x0123456789abcdef);
reader.set_position(0);
assert_eq!(reader.read_u32::<BigEndian>().unwrap(), 0x01234567);
reader.set_position(0);
assert_eq!(reader.read_u16::<BigEndian>().unwrap(), 0x0123);
}
#[test]
fn read_le() {
let buf: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
let mut reader = io::Cursor::new(buf);
reader.set_position(0);
assert_eq!(reader.read_u64::<LittleEndian>().unwrap(), 0xefcdab8967452301);
reader.set_position(0);
assert_eq!(reader.read_u32::<LittleEndian>().unwrap(), 0x67452301);
reader.set_position(0);
assert_eq!(reader.read_u16::<LittleEndian>().unwrap(), 0x2301);
}
#[test]
fn read_octet() {
let buf: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
let mut reader = io::Cursor::new(buf);
reader.set_position(0);
assert_eq!(reader.read_u8().unwrap(), 0x01);
}
#[test]
fn read_float() {
let mut buf: &[u8] = &[0x41, 0x21, 0xEB, 0x85];
assert_eq!(buf.read_f32::<BigEndian>().unwrap(), 10.12f32);
let mut buf: &[u8] = &[0x85, 0xEB, 0x21, 0x41];
assert_eq!(buf.read_f32::<LittleEndian>().unwrap(), 10.12f32);
let mut buf: &[u8] = &[0x40, 0x24, 0x3D, 0x70, 0xA3, 0xD7, 0x0A, 0x3D];
assert_eq!(buf.read_f64::<BigEndian>().unwrap(), 10.12f64);
let mut buf: &[u8] = &[0x3D, 0x0A, 0xD7, 0xA3, 0x70, 0x3D, 0x24, 0x40];
assert_eq!(buf.read_f64::<LittleEndian>().unwrap(), 10.12f64);
}
#[test]
fn read_exact() {
let mut buf: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(buf.read_exact(2).unwrap(), [1,2]);
assert_eq!(buf.read_exact(1).unwrap(), [3]);
assert_eq!(buf.read_exact(0).unwrap(), []);
assert_eq!(buf.read_exact(5).unwrap(), [4,5,6,7,8]);
assert_eq!(buf.read_exact(0).unwrap(), []);
assert!(buf.read_exact(1).is_err());
assert_eq!(buf.read_exact(0).unwrap(), []);
}

57
third_party/rust/podio/tests/io.rs поставляемый
Просмотреть файл

@ -1,57 +0,0 @@
extern crate podio;
use std::io::{self, Read};
use podio::ReadPodExt;
struct TestReader {
state: Option<io::Result<usize>>,
}
impl TestReader {
fn new(first_return: io::Result<usize>) -> TestReader {
TestReader { state: Some(first_return) }
}
fn get(&mut self) -> io::Result<u32> {
self.read_u32::<podio::LittleEndian>()
}
fn test(first_return: io::Result<usize>) -> io::Result<u32> {
TestReader::new(first_return).get()
}
}
impl Read for TestReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.state.take().unwrap_or(Ok(1)) {
Ok(n) => {
for i in buf.iter_mut().take(n) {
*i = 0xA5;
}
Ok(n)
},
e @ Err(..) => e,
}
}
}
#[test]
fn interrupted() {
// Getting an io::ErrorKind::Interrupted should be retried, and thus succeed
let first_read = Err(io::Error::new(io::ErrorKind::Interrupted, "Interrupted"));
assert_eq!(TestReader::test(first_read).unwrap(), 0xA5A5A5A5);
}
#[test]
fn eof() {
// Getting a Ok(0) implies an unexpected EOF
let first_read = Ok(0);
assert!(TestReader::test(first_read).is_err());
}
#[test]
fn err() {
// Getting any other error is still an error
let first_read = Err(io::Error::new(io::ErrorKind::Other, "Other"));
assert!(TestReader::test(first_read).is_err());
}

2
third_party/rust/zip/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"00f64858860f669e881bf7e797c7f75bcdeb11e299bc9c7344fe3082ccb8b628","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"face441ad06a7ef87477d5e96f3c456bef8f16662b03b5084d6fed7705fc4e99","appveyor.yml":"5c2aabf9d1fd01ca3dc33a14241bc0ce4a7327d2cbc3c3af350334bf5d107315","examples/extract.rs":"53b555617192330bd2f95235b82749905ad52617a5a3ba2648dbafbfff8a49a0","examples/extract_lorem.rs":"4e4e70927d2928a411ce4abe37ef4924c7156c4fd2697527c01fbd1797a76969","examples/stdin_info.rs":"54a9ce97b75a83c81de56c46cfe477dbd34dd98f739eb767f329b0e6dcb7490f","examples/write_dir.rs":"1a39da7b5d31997bf353a56d009ecdcf31da765f9ab191b20792e1904a594183","examples/write_sample.rs":"72a7c2db8074d20651ba04d0a49a7d6fb213ca674c63ab48db506deb69cba64c","script/doc-upload.cfg":"10684c8f5ef7e7388cfc4742ab9a060fe8f7fc1c51a63ede3c2443260ecc2d5e","src/compression.rs":"64ea510cfac9c9e5fed605a56fa44a7407df5cc51d4f63180bb2d4f2b307fdb2","src/cp437.rs":"7954c5b7df6f72fe3fe2c377c5de09973c2fa704c7ae0274a5490594e4b69517","src/crc32.rs":"3b503ee23047a4950e79f6956d0615f58c3cd8ded7f1fcd3f64e46dca37871da","src/lib.rs":"0afaf385ce7c7102016d2ba4c66c9cc7384ea710892477ed66bd1f560d83a732","src/read.rs":"d40a0b60c3b2dff73d6161e6d798a0e4aa0546a5f825bcddf6cf1bf52bf5366c","src/result.rs":"1006e46206a5b1491ed1d4fde0955a391df78cd42aa9582784b19170332a3783","src/spec.rs":"39b5e115745d962978e55ffb63ae2d62d0176c4c5ab457eea907a7aa33bf4e18","src/types.rs":"e2d7d3757013ca3ab149ee58fb5813fbeb7834e168870b28474816b47b869e61","src/write.rs":"59e3aff9339c9a16597101a5761391e93cc42eb99fb8c9057a6ee1e4e134da86","tests/data/invalid_offset.zip":"c5534a1803145f6344b04c437d436bd583852c78dd3937f4a73a2a39aa2d76b2","tests/data/mimetype.zip":"4bc6fd161d3e844b3e2b7f10fd0f9077ff565bb39fd2bfa34e7f8e9cd62db06d","tests/data/zip64_demo.zip":"223072a480f60d6a700e427b294e575ae2d6265f3e9881b647927f31d96c7e01","tests/invalid_date.rs":"e78b63b469d1f768bb452fefb84b013d3f9a4bf71dba2f9e12ff9e9c6ff8fd25"},"package":"36b9e08fb518a65cf7e08a1e482573eb87a2f4f8c6619316612a3c1f162fe822"}
{"files":{"CODE_OF_CONDUCT.md":"77930b2129928632cae79e10d0863885b34729e4f144f3ae5443cff65997196a","Cargo.lock":"93c43c455cb7331312fd980b3aabc02e68e67f9019b6502ba06ed93ee59553b5","Cargo.toml":"ca4e935d9ee6817239787ae2856dce0a25cae84affd469281691d4d37d9977fe","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"96dd07ada4821b66dfffee4c8a3689d8001f844ee7f19b70741a87cfa6195db4","benches/read_entry.rs":"700235ee560887f33da56895d2a4da901c070b2a6a59aef90331046af4ddadad","examples/extract.rs":"c6e16e42391ce294093866822dc2ee8cf45231d50101d619a0caffa1be633ae6","examples/extract_lorem.rs":"a5b33a31e7a2865e8ed7af52bab538268a8ba07cc4c3d8aa85811f80c86cb1fb","examples/file_info.rs":"e091923fc8c492255609efdd3c5fb656ad177601a73f4011005deab8096ca425","examples/stdin_info.rs":"f0bfed4016abbdb3922426f118bc990e6a1335bab878e1e146cb057f4e33d3cf","examples/write_dir.rs":"6f0b62022946765b6ef5f8ecac054a742d823ab0473152748d637da1568a9475","examples/write_sample.rs":"f57f463a9dea4eca7054d10d35bd8c65e1b6e0530bfbebf758006acea1e4ca0d","src/aes.rs":"c1b19bdf15c75cc27b5657d1dc574b5c5ebcdc7ca2573e9909cc6ba1ffe7f6d8","src/aes_ctr.rs":"6a7a07c9538daf53624818f82084c6655db3862ca00751f3679c8b0bc346b70d","src/compression.rs":"20c2f0c1857a3dce154505b5a73b6a22da867e16d676f0617a0e453f13cad175","src/cp437.rs":"e3a044ddefc947f6d9c26ba50ebd438955d90b8971ad8b15e5dd1194495f3b93","src/crc32.rs":"6c5a48834dfa1ab33590fcc63f4121ee6d3f8fbcc5018e905c4d8570096874cf","src/lib.rs":"7c2f6bc3dde9575eeeaef9569139f28351333c29362f74569e627ad7be5a10b2","src/read.rs":"8df99dbebdf0b856d4291b98ed99ac87b29069b60ed41fafab3acf0765f6a5e2","src/result.rs":"cfa7a545a56c6ce807c04675d70f9aed42d1aa19ffb717f4f94b8901a9f3728d","src/spec.rs":"e3b3429c814bb78efe14a8a48d53c30793f017b5d090889d72a2dc20b94c549a","src/types.rs":"b2979cdba63c9f5e9360578036541a80780300ca4febaece5730f670ab1b0a74","src/write.rs":"9e44a9093e83d41d798aa9ae652d4c7fabd54182a51fd22d34bdb68c3311f31c","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_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":"a39d88edcea901bba2bbdb277f073724a4aadd5c8e692256e9c57a09fb2fd357","tests/invalid_date.rs":"72d5425ffe2887e05646ba56f5116ac760cbeeb7889da5c9be612fe57477bc94","tests/issue_234.rs":"1a3d68d79108140100709c188841c6bf54af8500c819072a440ec72df5d8ab26","tests/zip64_large.rs":"083f070ae566e0a3b317bd94d51186b37f2ff88f225deae721b0b56be838da1c","tests/zip_comment_garbage.rs":"ab0e2e3ace1ca5459977a092ee96836f58c7f7a7cfc8de258ab448d8d24f1cbb","tests/zip_crypto.rs":"7f4f9670e5d971ac4234c7ab2cafecf43801baf0be0cfca6e34c651f6fc6a80d"},"package":"bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d"}

76
third_party/rust/zip/CODE_OF_CONDUCT.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ryan.levick@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

466
third_party/rust/zip/Cargo.lock сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,466 @@
# 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 = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[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.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
dependencies = [
"cfg-if",
"crc32fast",
"libc",
"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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f35facd4a5673cb5a48822be2be1d4236c1c99cb4113cab7061ac720d5bf859"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[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.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8"
dependencies = [
"base64ct",
"rand_core",
"subtle",
]
[[package]]
name = "pbkdf2"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7"
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.2"
dependencies = [
"aes",
"bencher",
"byteorder",
"bzip2",
"constant_time_eq",
"crc32fast",
"crossbeam-utils",
"flate2",
"getrandom",
"hmac",
"pbkdf2",
"sha1",
"time",
"walkdir",
"zstd",
]
[[package]]
name = "zstd"
version = "0.10.0+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "4.1.4+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee"
dependencies = [
"libc",
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "1.6.3+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8"
dependencies = [
"cc",
"libc",
]

84
third_party/rust/zip/Cargo.toml поставляемый
Просмотреть файл

@ -3,44 +3,84 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "zip"
version = "0.4.2"
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"]
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"
documentation = "http://mvdnes.github.io/rust-docs/zip-rs/zip/index.html"
keywords = ["zip", "archive"]
license = "MIT"
repository = "https://github.com/mvdnes/zip-rs.git"
[dependencies.bzip2]
version = "0.3"
repository = "https://github.com/zip-rs/zip.git"
[[bench]]
name = "read_entry"
harness = false
[dependencies.aes]
version = "0.7.5"
optional = true
[dependencies.byteorder]
version = "1.4.3"
[dependencies.bzip2]
version = "0.4.3"
optional = true
[dependencies.constant_time_eq]
version = "0.1.5"
optional = true
[dependencies.crc32fast]
version = "1.3.2"
[dependencies.flate2]
version = "1.0"
version = "1.0.22"
optional = true
default-features = false
[dependencies.msdos_time]
version = "0.1"
[dependencies.hmac]
version = "0.12.1"
features = ["reset"]
optional = true
[dependencies.podio]
version = "0.1"
[dependencies.pbkdf2]
version = "0.10.1"
optional = true
[dependencies.sha1]
version = "0.10.1"
optional = true
[dependencies.time]
version = "0.1"
version = "0.3.7"
features = ["formatting", "macros"]
optional = true
[dependencies.zstd]
version = "0.10.0"
optional = true
[dev-dependencies.bencher]
version = "0.1.5"
[dev-dependencies.getrandom]
version = "0.2.5"
[dev-dependencies.walkdir]
version = "1.0"
version = "2.3.2"
[features]
default = ["bzip2", "deflate"]
deflate = ["flate2", "flate2/rust_backend"]
deflate-miniz = ["flate2", "flate2/miniz-sys"]
deflate-zlib = ["flate2", "flate2/zlib"]
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"

48
third_party/rust/zip/README.md поставляемый
Просмотреть файл

@ -1,30 +1,33 @@
zip-rs
======
[![Build Status](https://travis-ci.org/mvdnes/zip-rs.svg?branch=master)](https://travis-ci.org/mvdnes/zip-rs)
[![Build status](https://ci.appveyor.com/api/projects/status/gsnpqcodg19iu253/branch/master?svg=true)](https://ci.appveyor.com/project/mvdnes/zip-rs/branch/master)
[![Build Status](https://img.shields.io/github/workflow/status/zip-rs/zip/CI)](https://github.com/zip-rs/zip/actions?query=branch%3Amaster+workflow%3ACI)
[![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](http://mvdnes.github.io/rust-docs/zip-rs/zip/index.html)
[Documentation](https://docs.rs/zip/0.6.2/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
----
A zip library for rust which supports reading and writing of simple ZIP files.
Supported compression formats:
* stored (i.e. none)
* deflate
* bzip2 (optional, enabled by default)
* bzip2
* zstd
Currently unsupported zip extensions:
* Encryption
* Multi-disk
We aim to support rust versions 1.20+.
Usage
-----
@ -32,34 +35,43 @@ With all default features:
```toml
[dependencies]
zip = "0.4"
zip = "0.6.2"
```
Without the default features:
```toml
[dependencies]
zip = { version = "0.4", default-features = false }
zip = { version = "0.6.2", default-features = false }
```
You can further control the backend of `deflate` compression method with these features:
* `deflate` (enabled by default) uses [miniz_oxide](https://github.com/Frommi/miniz_oxide)
* `deflate-miniz` uses [miniz](https://github.com/richgel999/miniz)
* `deflate-zlib` uses zlib
The features available are:
For example:
* `aes-crypto`: Enables decryption of files which were encrypted with AES. Supports AE-1 and AE-2 methods.
* `deflate`: Enables the deflate compression algorithm, which is the default for zip files.
* `bzip2`: Enables the BZip2 compression algorithm.
* `time`: Enables features using the [time](https://github.com/rust-lang-deprecated/time) crate.
* `zstd`: Enables the Zstandard compression algorithm.
```toml
[dependencies]
zip = { version = "0.4", features = ["deflate-zlib"], default-features = false }
```
All of these are enabled by default.
MSRV
----
Our current Minimum Supported Rust Version is **1.54.0**. When adding features,
we will follow these guidelines:
- We will always support the latest four minor Rust versions. This gives you a 6
month window to upgrade your compiler.
- Any change to the MSRV will be accompanied with a **minor** version bump
- While the crate is pre-1.0, this will be a change to the PATCH version.
Examples
--------
See the [examples directory](examples) for:
* How to write a file to a zip.
* how to write a directory of files to a zip (using [walkdir](https://github.com/BurntSushi/walkdir)).
* How to write a directory of files to a zip (using [walkdir](https://github.com/BurntSushi/walkdir)).
* How to extract a zip file.
* How to extract a single file from a zip.
* How to read a zip from the standard input.

45
third_party/rust/zip/appveyor.yml поставляемый
Просмотреть файл

@ -1,45 +0,0 @@
# Appveyor configuration template for Rust using rustup for Rust installation
# https://github.com/starkat99/appveyor-rust
os: Visual Studio 2015
environment:
matrix:
# Stable 64-bit MSVC
- channel: stable
target: x86_64-pc-windows-msvc
# Stable 32-bit MSVC
- channel: stable
target: i686-pc-windows-msvc
# Stable 64-bit GNU
- channel: stable
target: x86_64-pc-windows-gnu
# Stable 32-bit GNU
- channel: stable
target: i686-pc-windows-gnu
install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init -yv --default-toolchain %channel% --default-host %target%
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
- ps: |
if ($env:target -like "*-gnu" -And $env:target -like "x86_64-*") {
Start-FileDownload "http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/5.1.0/threads-win32/seh/x86_64-5.1.0-release-win32-seh-rt_v4-rev0.7z/download" -FileName mingw64.7z
7z x -oC:\ mingw64.7z > $null
$env:path = "C:\mingw64\bin;" + $env:path
gcc --version
}
elseif ($env:target -like "*-gnu") {
$env:path = "C:\mingw\bin;" + $env:path
gcc --version
}
- rustc -vV
- cargo -vV
build: false
test_script:
- cargo test
- cargo test --no-default-features
- cargo test --no-default-features --features "deflate-miniz"

43
third_party/rust/zip/benches/read_entry.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,43 @@
use bencher::{benchmark_group, benchmark_main};
use std::io::{Cursor, Read, Write};
use bencher::Bencher;
use getrandom::getrandom;
use zip::{ZipArchive, ZipWriter};
fn generate_random_archive(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);
writer.start_file("random.dat", options).unwrap();
let mut bytes = vec![0u8; size];
getrandom(&mut bytes).unwrap();
writer.write_all(&bytes).unwrap();
writer.finish().unwrap().into_inner()
}
fn read_entry(bench: &mut Bencher) {
let size = 1024 * 1024;
let bytes = generate_random_archive(size);
let mut archive = ZipArchive::new(Cursor::new(bytes.as_slice())).unwrap();
bench.iter(|| {
let mut file = archive.by_name("random.dat").unwrap();
let mut buf = [0u8; 1024];
loop {
let n = file.read(&mut buf).unwrap();
if n == 0 {
break;
}
}
});
bench.bytes = size as u64;
}
benchmark_group!(benches, read_entry);
benchmark_main!(benches);

23
third_party/rust/zip/examples/extract.rs поставляемый
Просмотреть файл

@ -1,7 +1,5 @@
extern crate zip;
use std::io;
use std::fs;
use std::io;
fn main() {
std::process::exit(real_main());
@ -20,7 +18,10 @@ fn real_main() -> i32 {
for i in 0..archive.len() {
let mut file = archive.by_index(i).unwrap();
let outpath = file.sanitized_name();
let outpath = match file.enclosed_name() {
Some(path) => path.to_owned(),
None => continue,
};
{
let comment = file.comment();
@ -29,11 +30,16 @@ fn real_main() -> i32 {
}
}
if (&*file.name()).ends_with('/') {
println!("File {} extracted to \"{}\"", i, outpath.as_path().display());
if (*file.name()).ends_with('/') {
println!("File {} extracted to \"{}\"", i, outpath.display());
fs::create_dir_all(&outpath).unwrap();
} else {
println!("File {} extracted to \"{}\" ({} bytes)", i, outpath.as_path().display(), file.size());
println!(
"File {} extracted to \"{}\" ({} bytes)",
i,
outpath.display(),
file.size()
);
if let Some(p) = outpath.parent() {
if !p.exists() {
fs::create_dir_all(&p).unwrap();
@ -53,5 +59,6 @@ fn real_main() -> i32 {
}
}
}
return 0;
0
}

Просмотреть файл

@ -1,14 +1,10 @@
use std::io::prelude::*;
extern crate zip;
fn main()
{
fn main() {
std::process::exit(real_main());
}
fn real_main() -> i32
{
fn real_main() -> i32 {
let args: Vec<_> = std::env::args().collect();
if args.len() < 2 {
println!("Usage: {} <filename>", args[0]);
@ -18,16 +14,18 @@ fn real_main() -> i32
let zipfile = std::fs::File::open(&fname).unwrap();
let mut archive = zip::ZipArchive::new(zipfile).unwrap();
let mut file = match archive.by_name("test/lorem_ipsum.txt")
{
let mut file = match archive.by_name("test/lorem_ipsum.txt") {
Ok(file) => file,
Err(..) => { println!("File test/lorem_ipsum.txt not found"); return 2;}
Err(..) => {
println!("File test/lorem_ipsum.txt not found");
return 2;
}
};
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
println!("{}", contents);
return 0;
0
}

54
third_party/rust/zip/examples/file_info.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,54 @@
use std::fs;
use std::io::BufReader;
fn main() {
std::process::exit(real_main());
}
fn real_main() -> i32 {
let args: Vec<_> = std::env::args().collect();
if args.len() < 2 {
println!("Usage: {} <filename>", args[0]);
return 1;
}
let fname = std::path::Path::new(&*args[1]);
let file = fs::File::open(&fname).unwrap();
let reader = BufReader::new(file);
let mut archive = zip::ZipArchive::new(reader).unwrap();
for i in 0..archive.len() {
let file = archive.by_index(i).unwrap();
let outpath = match file.enclosed_name() {
Some(path) => path,
None => {
println!("Entry {} has a suspicious path", file.name());
continue;
}
};
{
let comment = file.comment();
if !comment.is_empty() {
println!("Entry {} comment: {}", i, comment);
}
}
if (*file.name()).ends_with('/') {
println!(
"Entry {} is a directory with name \"{}\"",
i,
outpath.display()
);
} else {
println!(
"Entry {} is a file with name \"{}\" ({} bytes)",
i,
outpath.display(),
file.size()
);
}
}
0
}

16
third_party/rust/zip/examples/stdin_info.rs поставляемый
Просмотреть файл

@ -1,5 +1,3 @@
extern crate zip;
use std::io::{self, Read};
fn main() {
@ -14,18 +12,24 @@ fn real_main() -> i32 {
loop {
match zip::read::read_zipfile_from_stream(&mut stdin_handle) {
Ok(Some(mut file)) => {
println!("{}: {} bytes ({} bytes packed)", file.name(), file.size(), file.compressed_size());
println!(
"{}: {} bytes ({} bytes packed)",
file.name(),
file.size(),
file.compressed_size()
);
match file.read(&mut buf) {
Ok(n) => println!("The first {} bytes are: {:?}", n, &buf[0..n]),
Err(e) => println!("Could not read the file: {:?}", e),
};
},
}
Ok(None) => break,
Err(e) => {
println!("Error encountered while reading zip: {:?}", e);
return 1;
},
}
}
}
return 0;
0
}

91
third_party/rust/zip/examples/write_dir.rs поставляемый
Просмотреть файл

@ -1,56 +1,75 @@
extern crate zip;
extern crate walkdir;
use std::io::prelude::*;
use std::io::{Write, Seek};
use std::io::{Seek, Write};
use std::iter::Iterator;
use zip::write::FileOptions;
use zip::result::ZipError;
use zip::write::FileOptions;
use walkdir::{WalkDir, DirEntry};
use std::path::Path;
use std::fs::File;
use std::path::Path;
use walkdir::{DirEntry, WalkDir};
fn main() {
std::process::exit(real_main());
}
const METHOD_STORED : Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Stored);
const METHOD_STORED: Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Stored);
#[cfg(feature = "flate2")]
const METHOD_DEFLATED : Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Deflated);
#[cfg(not(feature = "flate2"))]
const METHOD_DEFLATED : Option<zip::CompressionMethod> = None;
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
const METHOD_DEFLATED: Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Deflated);
#[cfg(not(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
)))]
const METHOD_DEFLATED: Option<zip::CompressionMethod> = None;
#[cfg(feature = "bzip2")]
const METHOD_BZIP2 : Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Bzip2);
const METHOD_BZIP2: Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Bzip2);
#[cfg(not(feature = "bzip2"))]
const METHOD_BZIP2 : Option<zip::CompressionMethod> = None;
const METHOD_BZIP2: Option<zip::CompressionMethod> = None;
#[cfg(feature = "zstd")]
const METHOD_ZSTD: Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Zstd);
#[cfg(not(feature = "zstd"))]
const METHOD_ZSTD: Option<zip::CompressionMethod> = None;
fn real_main() -> i32 {
let args: Vec<_> = std::env::args().collect();
if args.len() < 3 {
println!("Usage: {} <source_directory> <destination_zipfile>",
args[0]);
println!(
"Usage: {} <source_directory> <destination_zipfile>",
args[0]
);
return 1;
}
let src_dir = &*args[1];
let dst_file = &*args[2];
for &method in [METHOD_STORED, METHOD_DEFLATED, METHOD_BZIP2].iter() {
if method.is_none() { continue }
for &method in [METHOD_STORED, METHOD_DEFLATED, METHOD_BZIP2, METHOD_ZSTD].iter() {
if method.is_none() {
continue;
}
match doit(src_dir, dst_file, method.unwrap()) {
Ok(_) => println!("done: {} written to {}", src_dir, dst_file),
Err(e) => println!("Error: {:?}", e),
}
}
return 0;
0
}
fn zip_dir<T>(it: &mut Iterator<Item=DirEntry>, prefix: &str, writer: T, method: zip::CompressionMethod)
-> zip::result::ZipResult<()>
where T: Write+Seek
fn zip_dir<T>(
it: &mut dyn Iterator<Item = DirEntry>,
prefix: &str,
writer: T,
method: zip::CompressionMethod,
) -> zip::result::ZipResult<()>
where
T: Write + Seek,
{
let mut zip = zip::ZipWriter::new(writer);
let options = FileOptions::default()
@ -60,26 +79,36 @@ fn zip_dir<T>(it: &mut Iterator<Item=DirEntry>, prefix: &str, writer: T, method:
let mut buffer = Vec::new();
for entry in it {
let path = entry.path();
let name = path.strip_prefix(Path::new(prefix))
.unwrap()
.to_str()
.unwrap();
let name = path.strip_prefix(Path::new(prefix)).unwrap();
// Write file or directory explicitly
// Some unzip tools unzip files with directory paths correctly, some do not!
if path.is_file() {
println!("adding {:?} as {:?} ...", path, name);
zip.start_file(name, options)?;
println!("adding file {:?} as {:?} ...", path, name);
#[allow(deprecated)]
zip.start_file_from_path(name, options)?;
let mut f = File::open(path)?;
f.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?;
buffer.clear();
} else if !name.as_os_str().is_empty() {
// Only if not root! Avoids path spec / warning
// and mapname conversion failed error on unzip
println!("adding dir {:?} as {:?} ...", path, name);
#[allow(deprecated)]
zip.add_directory_from_path(name, options)?;
}
}
zip.finish()?;
Result::Ok(())
}
fn doit(src_dir: &str, dst_file: &str, method: zip::CompressionMethod) -> zip::result::ZipResult<()> {
fn doit(
src_dir: &str,
dst_file: &str,
method: zip::CompressionMethod,
) -> zip::result::ZipResult<()> {
if !Path::new(src_dir).is_dir() {
return Err(ZipError::FileNotFound);
}
@ -87,10 +116,10 @@ fn doit(src_dir: &str, dst_file: &str, method: zip::CompressionMethod) -> zip::r
let path = Path::new(dst_file);
let file = File::create(&path).unwrap();
let walkdir = WalkDir::new(src_dir.to_string());
let walkdir = WalkDir::new(src_dir);
let it = walkdir.into_iter();
zip_dir(&mut it.filter_map(|e| e.ok()), src_dir, file, method)?;
Ok(())
}
}

34
third_party/rust/zip/examples/write_sample.rs поставляемый
Просмотреть файл

@ -1,15 +1,11 @@
use std::io::prelude::*;
use zip::write::FileOptions;
extern crate zip;
fn main()
{
fn main() {
std::process::exit(real_main());
}
fn real_main() -> i32
{
fn real_main() -> i32 {
let args: Vec<_> = std::env::args().collect();
if args.len() < 2 {
println!("Usage: {} <filename>", args[0]);
@ -17,36 +13,36 @@ fn real_main() -> i32
}
let filename = &*args[1];
match doit(filename)
{
match doit(filename) {
Ok(_) => println!("File written to {}", filename),
Err(e) => println!("Error: {:?}", e),
}
return 0;
0
}
fn doit(filename: &str) -> zip::result::ZipResult<()>
{
fn doit(filename: &str) -> zip::result::ZipResult<()> {
let path = std::path::Path::new(filename);
let file = std::fs::File::create(&path).unwrap();
let mut zip = zip::ZipWriter::new(file);
try!(zip.add_directory("test/", FileOptions::default()));
zip.add_directory("test/", Default::default())?;
let options = FileOptions::default().compression_method(zip::CompressionMethod::Stored).unix_permissions(0o755);
try!(zip.start_file("test/☃.txt", options));
try!(zip.write_all(b"Hello, World!\n"));
let options = FileOptions::default()
.compression_method(zip::CompressionMethod::Stored)
.unix_permissions(0o755);
zip.start_file("test/☃.txt", options)?;
zip.write_all(b"Hello, World!\n")?;
try!(zip.start_file("test/lorem_ipsum.txt", FileOptions::default()));
try!(zip.write_all(LOREM_IPSUM));
zip.start_file("test/lorem_ipsum.txt", Default::default())?;
zip.write_all(LOREM_IPSUM)?;
try!(zip.finish());
zip.finish()?;
Ok(())
}
const LOREM_IPSUM : &'static [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
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

3
third_party/rust/zip/script/doc-upload.cfg поставляемый
Просмотреть файл

@ -1,3 +0,0 @@
PROJECT_NAME=zip-rs
DOCS_REPO=mvdnes/rust-docs.git
DOC_RUST_VERSION=stable

185
third_party/rust/zip/src/aes.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,185 @@
//! Implementation of the AES decryption for zip files.
//!
//! This was implemented according to the [WinZip specification](https://www.winzip.com/win/en/aes_info.html).
//! Note that using CRC with AES depends on the used encryption specification, AE-1 or AE-2.
//! If the file is marked as encrypted with AE-2 the CRC field is ignored, even if it isn't set to 0.
use crate::aes_ctr;
use crate::types::AesMode;
use constant_time_eq::constant_time_eq;
use hmac::{Hmac, Mac};
use sha1::Sha1;
use std::io::{self, Read};
/// The length of the password verifcation value in bytes
const PWD_VERIFY_LENGTH: usize = 2;
/// The length of the authentication code in bytes
const AUTH_CODE_LENGTH: usize = 10;
/// The number of iterations used with PBKDF2
const ITERATION_COUNT: u32 = 1000;
/// Create a AesCipher depending on the used `AesMode` and the given `key`.
///
/// # Panics
///
/// This panics if `key` doesn't have the correct size for the chosen aes mode.
fn cipher_from_mode(aes_mode: AesMode, key: &[u8]) -> Box<dyn aes_ctr::AesCipher> {
match aes_mode {
AesMode::Aes128 => Box::new(aes_ctr::AesCtrZipKeyStream::<aes_ctr::Aes128>::new(key))
as Box<dyn aes_ctr::AesCipher>,
AesMode::Aes192 => Box::new(aes_ctr::AesCtrZipKeyStream::<aes_ctr::Aes192>::new(key))
as Box<dyn aes_ctr::AesCipher>,
AesMode::Aes256 => Box::new(aes_ctr::AesCtrZipKeyStream::<aes_ctr::Aes256>::new(key))
as Box<dyn aes_ctr::AesCipher>,
}
}
// An aes encrypted file starts with a salt, whose length depends on the used aes mode
// followed by a 2 byte password verification value
// then the variable length encrypted data
// and lastly a 10 byte authentication code
pub struct AesReader<R> {
reader: R,
aes_mode: AesMode,
data_length: u64,
}
impl<R: Read> AesReader<R> {
pub fn new(reader: R, aes_mode: AesMode, compressed_size: u64) -> AesReader<R> {
let data_length = compressed_size
- (PWD_VERIFY_LENGTH + AUTH_CODE_LENGTH + aes_mode.salt_length()) as u64;
Self {
reader,
aes_mode,
data_length,
}
}
/// Read the AES header bytes and validate the password.
///
/// Even if the validation succeeds, there is still a 1 in 65536 chance that an incorrect
/// password was provided.
/// It isn't possible to check the authentication code in this step. This will be done after
/// reading and decrypting the file.
///
/// # Returns
///
/// If the password verification failed `Ok(None)` will be returned to match the validate
/// method of ZipCryptoReader.
pub fn validate(mut self, password: &[u8]) -> io::Result<Option<AesReaderValid<R>>> {
let salt_length = self.aes_mode.salt_length();
let key_length = self.aes_mode.key_length();
let mut salt = vec![0; salt_length];
self.reader.read_exact(&mut salt)?;
// next are 2 bytes used for password verification
let mut pwd_verification_value = vec![0; PWD_VERIFY_LENGTH];
self.reader.read_exact(&mut pwd_verification_value)?;
// derive a key from the password and salt
// the length depends on the aes key length
let derived_key_len = 2 * key_length + PWD_VERIFY_LENGTH;
let mut derived_key: Vec<u8> = vec![0; derived_key_len];
// use PBKDF2 with HMAC-Sha1 to derive the key
pbkdf2::pbkdf2::<Hmac<Sha1>>(password, &salt, ITERATION_COUNT, &mut derived_key);
let decrypt_key = &derived_key[0..key_length];
let hmac_key = &derived_key[key_length..key_length * 2];
let pwd_verify = &derived_key[derived_key_len - 2..];
// the last 2 bytes should equal the password verification value
if pwd_verification_value != pwd_verify {
// wrong password
return Ok(None);
}
let cipher = cipher_from_mode(self.aes_mode, decrypt_key);
let hmac = Hmac::<Sha1>::new_from_slice(hmac_key).unwrap();
Ok(Some(AesReaderValid {
reader: self.reader,
data_remaining: self.data_length,
cipher,
hmac,
finalized: false,
}))
}
}
/// A reader for aes encrypted files, which has already passed the first password check.
///
/// There is a 1 in 65536 chance that an invalid password passes that check.
/// After the data has been read and decrypted an HMAC will be checked and provide a final means
/// to check if either the password is invalid or if the data has been changed.
pub struct AesReaderValid<R: Read> {
reader: R,
data_remaining: u64,
cipher: Box<dyn aes_ctr::AesCipher>,
hmac: Hmac<Sha1>,
finalized: bool,
}
impl<R: Read> Read for AesReaderValid<R> {
/// This implementation does not fulfill all requirements set in the trait documentation.
///
/// ```txt
/// "If an error is returned then it must be guaranteed that no bytes were read."
/// ```
///
/// Whether this applies to errors that occur while reading the encrypted data depends on the
/// underlying reader. If the error occurs while verifying the HMAC, the reader might become
/// practically unusable, since its position after the error is not known.
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if self.data_remaining == 0 {
return Ok(0);
}
// get the number of bytes to read, compare as u64 to make sure we can read more than
// 2^32 bytes even on 32 bit systems.
let bytes_to_read = self.data_remaining.min(buf.len() as u64) as usize;
let read = self.reader.read(&mut buf[0..bytes_to_read])?;
self.data_remaining -= read as u64;
// Update the hmac with the encrypted data
self.hmac.update(&buf[0..read]);
// decrypt the data
self.cipher.crypt_in_place(&mut buf[0..read]);
// if there is no data left to read, check the integrity of the data
if self.data_remaining == 0 {
assert!(
!self.finalized,
"Tried to use an already finalized HMAC. This is a bug!"
);
self.finalized = true;
// Zip uses HMAC-Sha1-80, which only uses the first half of the hash
// see https://www.winzip.com/win/en/aes_info.html#auth-faq
let mut read_auth_code = [0; AUTH_CODE_LENGTH];
self.reader.read_exact(&mut read_auth_code)?;
let computed_auth_code = &self.hmac.finalize_reset().into_bytes()[0..AUTH_CODE_LENGTH];
// use constant time comparison to mitigate timing attacks
if !constant_time_eq(computed_auth_code, &read_auth_code) {
return Err(
io::Error::new(
io::ErrorKind::InvalidData,
"Invalid authentication code, this could be due to an invalid password or errors in the data"
)
);
}
}
Ok(read)
}
}
impl<R: Read> AesReaderValid<R> {
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.reader
}
}

281
third_party/rust/zip/src/aes_ctr.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,281 @@
//! A counter mode (CTR) for AES to work with the encryption used in zip files.
//!
//! 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.
use aes::cipher::generic_array::GenericArray;
use aes::{BlockEncrypt, NewBlockCipher};
use byteorder::WriteBytesExt;
use std::{any, fmt};
/// Internal block size of an AES cipher.
const AES_BLOCK_SIZE: usize = 16;
/// AES-128.
#[derive(Debug)]
pub struct Aes128;
/// AES-192
#[derive(Debug)]
pub struct Aes192;
/// AES-256.
#[derive(Debug)]
pub struct Aes256;
/// An AES cipher kind.
pub trait AesKind {
/// Key type.
type Key: AsRef<[u8]>;
/// Cipher used to decrypt.
type Cipher;
}
impl AesKind for Aes128 {
type Key = [u8; 16];
type Cipher = aes::Aes128;
}
impl AesKind for Aes192 {
type Key = [u8; 24];
type Cipher = aes::Aes192;
}
impl AesKind for Aes256 {
type Key = [u8; 32];
type Cipher = aes::Aes256;
}
/// An AES-CTR key stream generator.
///
/// Implements the slightly non-standard AES-CTR variant used by WinZip AES encryption.
///
/// Typical AES-CTR implementations combine a nonce with a 64 bit counter. WinZIP AES instead uses
/// no nonce and also uses a different byte order (little endian) than NIST (big endian).
///
/// The stream implements the `Read` trait; encryption or decryption is performed by XOR-ing the
/// bytes from the key stream with the ciphertext/plaintext.
pub struct AesCtrZipKeyStream<C: AesKind> {
/// Current AES counter.
counter: u128,
/// AES cipher instance.
cipher: C::Cipher,
/// Stores the currently available keystream bytes.
buffer: [u8; AES_BLOCK_SIZE],
/// Number of bytes already used up from `buffer`.
pos: usize,
}
impl<C> fmt::Debug for AesCtrZipKeyStream<C>
where
C: AesKind,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"AesCtrZipKeyStream<{}>(counter: {})",
any::type_name::<C>(),
self.counter
)
}
}
impl<C> AesCtrZipKeyStream<C>
where
C: AesKind,
C::Cipher: NewBlockCipher,
{
/// Creates a new zip variant AES-CTR key stream.
///
/// # Panics
///
/// This panics if `key` doesn't have the correct size for cipher `C`.
pub fn new(key: &[u8]) -> AesCtrZipKeyStream<C> {
AesCtrZipKeyStream {
counter: 1,
cipher: C::Cipher::new(GenericArray::from_slice(key)),
buffer: [0u8; AES_BLOCK_SIZE],
pos: AES_BLOCK_SIZE,
}
}
}
impl<C> AesCipher for AesCtrZipKeyStream<C>
where
C: AesKind,
C::Cipher: BlockEncrypt,
{
/// Decrypt or encrypt `target`.
#[inline]
fn crypt_in_place(&mut self, mut target: &mut [u8]) {
while !target.is_empty() {
if self.pos == AES_BLOCK_SIZE {
// Note: AES block size is always 16 bytes, same as u128.
self.buffer
.as_mut()
.write_u128::<byteorder::LittleEndian>(self.counter)
.expect("did not expect u128 le conversion to fail");
self.cipher
.encrypt_block(GenericArray::from_mut_slice(&mut self.buffer));
self.counter += 1;
self.pos = 0;
}
let target_len = target.len().min(AES_BLOCK_SIZE - self.pos);
xor(
&mut target[0..target_len],
&self.buffer[self.pos..(self.pos + target_len)],
);
target = &mut target[target_len..];
self.pos += target_len;
}
}
}
/// This trait allows using generic AES ciphers with different key sizes.
pub trait AesCipher {
fn crypt_in_place(&mut self, target: &mut [u8]);
}
/// XORs a slice in place with another slice.
#[inline]
fn xor(dest: &mut [u8], src: &[u8]) {
assert_eq!(dest.len(), src.len());
for (lhs, rhs) in dest.iter_mut().zip(src.iter()) {
*lhs ^= *rhs;
}
}
#[cfg(test)]
mod tests {
use super::{Aes128, Aes192, Aes256, AesCipher, AesCtrZipKeyStream, AesKind};
use aes::{BlockEncrypt, NewBlockCipher};
/// 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,
{
let mut key_stream = AesCtrZipKeyStream::<Aes>::new(key);
let mut plaintext: Vec<u8> = ciphertext.to_vec();
key_stream.crypt_in_place(plaintext.as_mut_slice());
assert_eq!(plaintext, expected_plaintext.to_vec());
// Round-tripping should yield the ciphertext again.
let mut key_stream = AesCtrZipKeyStream::<Aes>::new(key);
key_stream.crypt_in_place(&mut plaintext);
assert_eq!(plaintext, ciphertext.to_vec());
}
#[test]
#[should_panic]
fn new_with_wrong_key_size() {
AesCtrZipKeyStream::<Aes128>::new(&[1, 2, 3, 4, 5]);
}
// The data used in these tests was generated with p7zip without any compression.
// It's not possible to recreate the exact same data, since a random salt is used for encryption.
// `7z a -phelloworld -mem=AES256 -mx=0 aes256_40byte.zip 40byte_data.txt`
#[test]
fn crypt_aes_256_0_byte() {
let mut ciphertext = [];
let expected_plaintext = &[];
let key = [
0x0b, 0xec, 0x2e, 0xf2, 0x46, 0xf0, 0x7e, 0x35, 0x16, 0x54, 0xe0, 0x98, 0x10, 0xb3,
0x18, 0x55, 0x24, 0xa3, 0x9e, 0x0e, 0x40, 0xe7, 0x92, 0xad, 0xb2, 0x8a, 0x48, 0xf4,
0x5c, 0xd0, 0xc0, 0x54,
];
roundtrip::<Aes256>(&key, &mut ciphertext, expected_plaintext);
}
#[test]
fn crypt_aes_128_5_byte() {
let mut ciphertext = [0x98, 0xa9, 0x8c, 0x26, 0x0e];
let expected_plaintext = b"asdf\n";
let key = [
0xe0, 0x25, 0x7b, 0x57, 0x97, 0x6a, 0xa4, 0x23, 0xab, 0x94, 0xaa, 0x44, 0xfd, 0x47,
0x4f, 0xa5,
];
roundtrip::<Aes128>(&key, &mut ciphertext, expected_plaintext);
}
#[test]
fn crypt_aes_192_5_byte() {
let mut ciphertext = [0x36, 0x55, 0x5c, 0x61, 0x3c];
let expected_plaintext = b"asdf\n";
let key = [
0xe4, 0x4a, 0x88, 0x52, 0x8f, 0xf7, 0x0b, 0x81, 0x7b, 0x75, 0xf1, 0x74, 0x21, 0x37,
0x8c, 0x90, 0xad, 0xbe, 0x4a, 0x65, 0xa8, 0x96, 0x0e, 0xcc,
];
roundtrip::<Aes192>(&key, &mut ciphertext, expected_plaintext);
}
#[test]
fn crypt_aes_256_5_byte() {
let mut ciphertext = [0xc2, 0x47, 0xc0, 0xdc, 0x56];
let expected_plaintext = b"asdf\n";
let key = [
0x79, 0x5e, 0x17, 0xf2, 0xc6, 0x3d, 0x28, 0x9b, 0x4b, 0x4b, 0xbb, 0xa9, 0xba, 0xc9,
0xa5, 0xee, 0x3a, 0x4f, 0x0f, 0x4b, 0x29, 0xbd, 0xe9, 0xb8, 0x41, 0x9c, 0x41, 0xa5,
0x15, 0xb2, 0x86, 0xab,
];
roundtrip::<Aes256>(&key, &mut ciphertext, expected_plaintext);
}
#[test]
fn crypt_aes_128_40_byte() {
let mut ciphertext = [
0xcf, 0x72, 0x6b, 0xa1, 0xb2, 0x0f, 0xdf, 0xaa, 0x10, 0xad, 0x9c, 0x7f, 0x6d, 0x1c,
0x8d, 0xb5, 0x16, 0x7e, 0xbb, 0x11, 0x69, 0x52, 0x8c, 0x89, 0x80, 0x32, 0xaa, 0x76,
0xa6, 0x18, 0x31, 0x98, 0xee, 0xdd, 0x22, 0x68, 0xb7, 0xe6, 0x77, 0xd2,
];
let expected_plaintext = b"Lorem ipsum dolor sit amet, consectetur\n";
let key = [
0x43, 0x2b, 0x6d, 0xbe, 0x05, 0x76, 0x6c, 0x9e, 0xde, 0xca, 0x3b, 0xf8, 0xaf, 0x5d,
0x81, 0xb6,
];
roundtrip::<Aes128>(&key, &mut ciphertext, expected_plaintext);
}
#[test]
fn crypt_aes_192_40_byte() {
let mut ciphertext = [
0xa6, 0xfc, 0x52, 0x79, 0x2c, 0x6c, 0xfe, 0x68, 0xb1, 0xa8, 0xb3, 0x07, 0x52, 0x8b,
0x82, 0xa6, 0x87, 0x9c, 0x72, 0x42, 0x3a, 0xf8, 0xc6, 0xa9, 0xc9, 0xfb, 0x61, 0x19,
0x37, 0xb9, 0x56, 0x62, 0xf4, 0xfc, 0x5e, 0x7a, 0xdd, 0x55, 0x0a, 0x48,
];
let expected_plaintext = b"Lorem ipsum dolor sit amet, consectetur\n";
let key = [
0xac, 0x92, 0x41, 0xba, 0xde, 0xd9, 0x02, 0xfe, 0x40, 0x92, 0x20, 0xf6, 0x56, 0x03,
0xfe, 0xae, 0x1b, 0xba, 0x01, 0x97, 0x97, 0x79, 0xbb, 0xa6,
];
roundtrip::<Aes192>(&key, &mut ciphertext, expected_plaintext);
}
#[test]
fn crypt_aes_256_40_byte() {
let mut ciphertext = [
0xa9, 0x99, 0xbd, 0xea, 0x82, 0x9b, 0x8f, 0x2f, 0xb7, 0x52, 0x2f, 0x6b, 0xd8, 0xf6,
0xab, 0x0e, 0x24, 0x51, 0x9e, 0x18, 0x0f, 0xc0, 0x8f, 0x54, 0x15, 0x80, 0xae, 0xbc,
0xa0, 0x5c, 0x8a, 0x11, 0x8d, 0x14, 0x7e, 0xc5, 0xb4, 0xae, 0xd3, 0x37,
];
let expected_plaintext = b"Lorem ipsum dolor sit amet, consectetur\n";
let key = [
0x64, 0x7c, 0x7a, 0xde, 0xf0, 0xf2, 0x61, 0x49, 0x1c, 0xf1, 0xf1, 0xe3, 0x37, 0xfc,
0xe1, 0x4d, 0x4a, 0x77, 0xd4, 0xeb, 0x9e, 0x3d, 0x75, 0xce, 0x9a, 0x3e, 0x10, 0x50,
0xc2, 0x07, 0x36, 0xb6,
];
roundtrip::<Aes256>(&key, &mut ciphertext, expected_plaintext);
}
}

167
third_party/rust/zip/src/compression.rs поставляемый
Просмотреть файл

@ -2,99 +2,192 @@
use std::fmt;
/// Compression methods for the contents of a ZIP file.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum CompressionMethod
{
/// The file is stored (no compression)
#[allow(deprecated)]
/// Identifies the storage format used to compress a file within a ZIP archive.
///
/// Each file's compression method is stored alongside it, allowing the
/// contents to be read without context.
///
/// When creating ZIP files, you may choose the method to use with
/// [`crate::write::FileOptions::compression_method`]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[non_exhaustive]
pub enum CompressionMethod {
/// Store the file as is
Stored,
/// The file is Deflated
#[cfg(feature = "flate2")]
/// Compress the file using Deflate
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
Deflated,
/// File is compressed using BZIP2 algorithm
/// Compress the file using BZIP2
#[cfg(feature = "bzip2")]
Bzip2,
/// Encrypted using AES.
///
/// The actual compression method has to be taken from the AES extra data field
/// or from `ZipFileData`.
#[cfg(feature = "aes-crypto")]
Aes,
/// Compress the file using ZStandard
#[cfg(feature = "zstd")]
Zstd,
/// Unsupported compression method
#[deprecated(since = "0.5.7", note = "use the constants instead")]
Unsupported(u16),
}
#[allow(deprecated, missing_docs)]
/// All compression methods defined for the ZIP format
impl CompressionMethod {
pub const STORE: Self = CompressionMethod::Stored;
pub const SHRINK: Self = CompressionMethod::Unsupported(1);
pub const REDUCE_1: Self = CompressionMethod::Unsupported(2);
pub const REDUCE_2: Self = CompressionMethod::Unsupported(3);
pub const REDUCE_3: Self = CompressionMethod::Unsupported(4);
pub const REDUCE_4: Self = CompressionMethod::Unsupported(5);
pub const IMPLODE: Self = CompressionMethod::Unsupported(6);
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
pub const DEFLATE: Self = CompressionMethod::Deflated;
#[cfg(not(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
)))]
pub const DEFLATE: Self = CompressionMethod::Unsupported(8);
pub const DEFLATE64: Self = CompressionMethod::Unsupported(9);
pub const PKWARE_IMPLODE: Self = CompressionMethod::Unsupported(10);
#[cfg(feature = "bzip2")]
pub const BZIP2: Self = CompressionMethod::Bzip2;
#[cfg(not(feature = "bzip2"))]
pub const BZIP2: Self = CompressionMethod::Unsupported(12);
pub const LZMA: Self = CompressionMethod::Unsupported(14);
pub const IBM_ZOS_CMPSC: Self = CompressionMethod::Unsupported(16);
pub const IBM_TERSE: Self = CompressionMethod::Unsupported(18);
pub const ZSTD_DEPRECATED: Self = CompressionMethod::Unsupported(20);
#[cfg(feature = "zstd")]
pub const ZSTD: Self = CompressionMethod::Zstd;
#[cfg(not(feature = "zstd"))]
pub const ZSTD: Self = CompressionMethod::Unsupported(93);
pub const MP3: Self = CompressionMethod::Unsupported(94);
pub const XZ: Self = CompressionMethod::Unsupported(95);
pub const JPEG: Self = CompressionMethod::Unsupported(96);
pub const WAVPACK: Self = CompressionMethod::Unsupported(97);
pub const PPMD: Self = CompressionMethod::Unsupported(98);
#[cfg(feature = "aes-crypto")]
pub const AES: Self = CompressionMethod::Aes;
#[cfg(not(feature = "aes-crypto"))]
pub const AES: Self = CompressionMethod::Unsupported(99);
}
impl CompressionMethod {
/// Converts an u16 to its corresponding CompressionMethod
#[deprecated(
since = "0.5.7",
note = "use a constant to construct a compression method"
)]
pub fn from_u16(val: u16) -> CompressionMethod {
#[allow(deprecated)]
match val {
0 => CompressionMethod::Stored,
#[cfg(feature = "flate2")]
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
8 => CompressionMethod::Deflated,
#[cfg(feature = "bzip2")]
12 => CompressionMethod::Bzip2,
#[cfg(feature = "zstd")]
93 => CompressionMethod::Zstd,
#[cfg(feature = "aes-crypto")]
99 => CompressionMethod::Aes,
v => CompressionMethod::Unsupported(v),
}
}
/// Converts a CompressionMethod to a u16
#[deprecated(
since = "0.5.7",
note = "to match on other compression methods, use a constant"
)]
pub fn to_u16(self) -> u16 {
#[allow(deprecated)]
match self {
CompressionMethod::Stored => 0,
#[cfg(feature = "flate2")]
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
CompressionMethod::Deflated => 8,
#[cfg(feature = "bzip2")]
CompressionMethod::Bzip2 => 12,
#[cfg(feature = "aes-crypto")]
CompressionMethod::Aes => 99,
#[cfg(feature = "zstd")]
CompressionMethod::Zstd => 93,
CompressionMethod::Unsupported(v) => v,
}
}
}
impl fmt::Display for CompressionMethod {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Just duplicate what the Debug format looks like, i.e, the enum key:
write!(f, "{:?}", self)
}
}
/// The compression methods which have been implemented.
pub const SUPPORTED_COMPRESSION_METHODS: &[CompressionMethod] = &[
CompressionMethod::Stored,
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
CompressionMethod::Deflated,
#[cfg(feature = "bzip2")]
CompressionMethod::Bzip2,
#[cfg(feature = "zstd")]
CompressionMethod::Zstd,
];
#[cfg(test)]
mod test {
use super::CompressionMethod;
use super::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};
#[test]
fn from_eq_to() {
for v in 0..(::std::u16::MAX as u32 + 1)
{
for v in 0..(u16::MAX as u32 + 1) {
#[allow(deprecated)]
let from = CompressionMethod::from_u16(v as u16);
#[allow(deprecated)]
let to = from.to_u16() as u32;
assert_eq!(v, to);
}
}
#[cfg(all(not(feature = "bzip2"), feature = "flate2"))]
fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored, CompressionMethod::Deflated]
}
#[cfg(all(not(feature = "flate2"), feature = "bzip2"))]
fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored, CompressionMethod::Bzip2]
}
#[cfg(all(feature = "bzip2", feature = "flate2"))]
fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored, CompressionMethod::Deflated, CompressionMethod::Bzip2]
}
#[cfg(all(not(feature = "bzip2"), not(feature = "flate2")))]
fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored]
}
#[test]
fn to_eq_from() {
fn check_match(method: CompressionMethod) {
#[allow(deprecated)]
let to = method.to_u16();
#[allow(deprecated)]
let from = CompressionMethod::from_u16(to);
#[allow(deprecated)]
let back = from.to_u16();
assert_eq!(to, back);
}
for method in methods() {
for &method in SUPPORTED_COMPRESSION_METHODS {
check_match(method);
}
}
@ -107,7 +200,7 @@ mod test {
assert_eq!(debug_str, display_str);
}
for method in methods() {
for &method in SUPPORTED_COMPRESSION_METHODS {
check_match(method);
}
}

34
third_party/rust/zip/src/cp437.rs поставляемый
Просмотреть файл

@ -6,19 +6,18 @@ pub trait FromCp437 {
type Target;
/// Function that does the conversion from cp437.
/// Gennerally allocations will be avoided if all data falls into the ASCII range.
/// Generally allocations will be avoided if all data falls into the ASCII range.
#[allow(clippy::wrong_self_convention)]
fn from_cp437(self) -> Self::Target;
}
impl<'a> FromCp437 for &'a [u8] {
type Target = ::std::borrow::Cow<'a, str>;
fn from_cp437(self) -> Self::Target
{
fn from_cp437(self) -> Self::Target {
if self.iter().all(|c| *c < 0x80) {
::std::str::from_utf8(self).unwrap().into()
}
else {
} else {
self.iter().map(|c| to_char(*c)).collect::<String>().into()
}
}
@ -30,18 +29,15 @@ impl FromCp437 for Vec<u8> {
fn from_cp437(self) -> Self::Target {
if self.iter().all(|c| *c < 0x80) {
String::from_utf8(self).unwrap()
}
else {
self.into_iter().map(|c| to_char(c)).collect()
} else {
self.into_iter().map(to_char).collect()
}
}
}
fn to_char(input: u8) -> char
{
let output = match input
{
0x00 ... 0x7f => input as u32,
fn to_char(input: u8) -> char {
let output = match input {
0x00..=0x7f => input as u32,
0x80 => 0x00c7,
0x81 => 0x00fc,
0x82 => 0x00e9,
@ -170,26 +166,22 @@ fn to_char(input: u8) -> char
0xfd => 0x00b2,
0xfe => 0x25a0,
0xff => 0x00a0,
_ => unreachable!(),
};
::std::char::from_u32(output).unwrap()
}
#[cfg(test)]
mod test
{
mod test {
#[test]
fn to_char_valid()
{
for i in 0x00_u32 .. 0x100
{
fn to_char_valid() {
for i in 0x00_u32..0x100 {
super::to_char(i as u8);
}
}
#[test]
fn ascii() {
for i in 0x00 .. 0x80 {
for i in 0x00..0x80 {
assert_eq!(super::to_char(i), i as char);
}
}

156
third_party/rust/zip/src/crc32.rs поставляемый
Просмотреть файл

@ -3,89 +3,32 @@
use std::io;
use std::io::prelude::*;
const CRC32_TABLE : [u32; 256] = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
];
/// Update the checksum prev based upon the contents of buf.
pub fn update(prev: u32, buf: &[u8]) -> u32
{
let mut crc = !prev;
for &byte in buf.iter()
{
crc = CRC32_TABLE[((crc as u8) ^ byte) as usize] ^ (crc >> 8);
}
!crc
}
use crc32fast::Hasher;
/// Reader that validates the CRC32 when it reaches the EOF.
pub struct Crc32Reader<R>
{
pub struct Crc32Reader<R> {
inner: R,
crc: u32,
hasher: Hasher,
check: u32,
/// Signals if `inner` stores aes encrypted data.
/// AE-2 encrypted data doesn't use crc and sets the value to 0.
ae2_encrypted: bool,
}
impl<R> Crc32Reader<R>
{
/// Get a new Crc32Reader which check the inner reader against checksum.
pub fn new(inner: R, checksum: u32) -> Crc32Reader<R>
{
Crc32Reader
{
inner: inner,
crc: 0,
impl<R> Crc32Reader<R> {
/// Get a new Crc32Reader which checks the inner reader against checksum.
/// The check is disabled if `ae2_encrypted == true`.
pub(crate) fn new(inner: R, checksum: u32, ae2_encrypted: bool) -> Crc32Reader<R> {
Crc32Reader {
inner,
hasher: Hasher::new(),
check: checksum,
ae2_encrypted,
}
}
fn check_matches(&self) -> bool
{
self.check == self.crc
fn check_matches(&self) -> bool {
self.check == self.hasher.clone().finalize()
}
pub fn into_inner(self) -> R {
@ -93,36 +36,65 @@ impl<R> Crc32Reader<R>
}
}
impl<R: Read> Read for Crc32Reader<R>
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
{
let count = match self.inner.read(buf)
{
Ok(0) if !self.check_matches() => { return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum")) },
impl<R: Read> Read for Crc32Reader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let invalid_check = !buf.is_empty() && !self.check_matches() && !self.ae2_encrypted;
let count = match self.inner.read(buf) {
Ok(0) if invalid_check => {
return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum"))
}
Ok(n) => n,
Err(e) => return Err(e),
};
self.crc = update(self.crc, &buf[0..count]);
self.hasher.update(&buf[0..count]);
Ok(count)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io::Read;
#[test]
fn samples() {
assert_eq!(super::update(0, b""), 0);
fn test_empty_reader() {
let data: &[u8] = b"";
let mut buf = [0; 1];
// test vectors from the iPXE project (input and output are bitwise negated)
assert_eq!(super::update(!0x12345678, b""), !0x12345678);
assert_eq!(super::update(!0xffffffff, b"hello world"), !0xf2b5ee7a);
assert_eq!(super::update(!0xffffffff, b"hello"), !0xc9ef5979);
assert_eq!(super::update(!0xc9ef5979, b" world"), !0xf2b5ee7a);
let mut reader = Crc32Reader::new(data, 0, false);
assert_eq!(reader.read(&mut buf).unwrap(), 0);
// Some vectors found on Rosetta code
assert_eq!(super::update(0, b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), 0x190A55AD);
assert_eq!(super::update(0, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"), 0xFF6CAB0B);
assert_eq!(super::update(0, b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"), 0x91267E8A);
let mut reader = Crc32Reader::new(data, 1, false);
assert!(reader
.read(&mut buf)
.unwrap_err()
.to_string()
.contains("Invalid checksum"));
}
#[test]
fn test_byte_by_byte() {
let data: &[u8] = b"1234";
let mut buf = [0; 1];
let mut reader = Crc32Reader::new(data, 0x9be3e0a3, false);
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.read(&mut buf).unwrap(), 0);
// Can keep reading 0 bytes after the end
assert_eq!(reader.read(&mut buf).unwrap(), 0);
}
#[test]
fn test_zero_read() {
let data: &[u8] = b"1234";
let mut buf = [0; 5];
let mut reader = Crc32Reader::new(data, 0x9be3e0a3, false);
assert_eq!(reader.read(&mut buf[..0]).unwrap(), 0);
assert_eq!(reader.read(&mut buf).unwrap(), 4);
}
}

54
third_party/rust/zip/src/lib.rs поставляемый
Просмотреть файл

@ -1,24 +1,44 @@
//! A basic ZipReader/Writer crate
//! A library for reading and writing ZIP archives.
//! ZIP is a format designed for cross-platform file "archiving".
//! That is, storing a collection of files in a single datastream
//! to make them easier to share between computers.
//! Additionally, ZIP is able to compress and encrypt files in its
//! archives.
//!
//! The current implementation is based on [PKWARE's APPNOTE.TXT v6.3.9](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
//!
//! ---
//!
//! [`zip`](`crate`) has support for the most common ZIP archives found in common use.
//! However, in special cases,
//! there are some zip archives that are difficult to read or write.
//!
//! This is a list of supported features:
//!
//! | | Reading | Writing |
//! | ------- | ------ | ------- |
//! | Deflate | ✅ [->](`crate::ZipArchive::by_name`) | ✅ [->](`crate::write::FileOptions::compression_method`) |
//!
//!
//!
#![warn(missing_docs)]
#[cfg(feature = "bzip2")]
extern crate bzip2;
#[cfg(feature = "flate2")]
extern crate flate2;
extern crate msdos_time;
extern crate podio;
extern crate time;
pub use crate::compression::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};
pub use crate::read::ZipArchive;
pub use crate::types::DateTime;
pub use crate::write::ZipWriter;
pub use read::ZipArchive;
pub use write::ZipWriter;
pub use compression::CompressionMethod;
mod spec;
mod crc32;
mod types;
pub mod read;
#[cfg(feature = "aes-crypto")]
mod aes;
#[cfg(feature = "aes-crypto")]
mod aes_ctr;
mod compression;
pub mod write;
mod cp437;
mod crc32;
pub mod read;
pub mod result;
mod spec;
mod types;
pub mod write;
mod zipcrypto;

1229
third_party/rust/zip/src/read.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

109
third_party/rust/zip/src/result.rs поставляемый
Просмотреть файл

@ -1,17 +1,27 @@
//! Error types that can be emitted from this library
use std::convert;
use std::error;
use std::error::Error;
use std::fmt;
use std::io;
/// Generic result type with ZipError as its error variant
pub type ZipResult<T> = Result<T, ZipError>;
/// The given password is wrong
#[derive(Debug)]
pub struct InvalidPassword;
impl fmt::Display for InvalidPassword {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "invalid password for file in archive")
}
}
impl Error for InvalidPassword {}
/// Error type for Zip
#[derive(Debug)]
pub enum ZipError
{
pub enum ZipError {
/// An Error caused by I/O
Io(io::Error),
@ -25,70 +35,49 @@ pub enum ZipError
FileNotFound,
}
impl ZipError
{
fn detail(&self) -> ::std::borrow::Cow<str>
{
use std::error::Error;
match *self
{
ZipError::Io(ref io_err) => {
("Io Error: ".to_string() + (io_err as &error::Error).description()).into()
},
ZipError::InvalidArchive(msg) | ZipError::UnsupportedArchive(msg) => {
(self.description().to_string() + ": " + msg).into()
},
ZipError::FileNotFound => {
self.description().into()
},
}
}
}
impl convert::From<io::Error> for ZipError
{
fn from(err: io::Error) -> ZipError
{
impl From<io::Error> for ZipError {
fn from(err: io::Error) -> ZipError {
ZipError::Io(err)
}
}
impl convert::From<ZipError> for io::Error
{
fn from(err: ZipError) -> io::Error
{
io::Error::new(io::ErrorKind::Other, err)
}
}
impl fmt::Display for ZipError
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>
{
fmt.write_str(&*self.detail())
}
}
impl error::Error for ZipError
{
fn description(&self) -> &str
{
match *self
{
ZipError::Io(ref io_err) => (io_err as &error::Error).description(),
ZipError::InvalidArchive(..) => "Invalid Zip archive",
ZipError::UnsupportedArchive(..) => "Unsupported Zip archive",
ZipError::FileNotFound => "Specified file not found in archive",
impl fmt::Display for ZipError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
ZipError::Io(err) => write!(fmt, "{}", err),
ZipError::InvalidArchive(err) => write!(fmt, "invalid Zip archive: {}", err),
ZipError::UnsupportedArchive(err) => write!(fmt, "unsupported Zip archive: {}", err),
ZipError::FileNotFound => write!(fmt, "specified file not found in archive"),
}
}
}
fn cause(&self) -> Option<&error::Error>
{
match *self
{
ZipError::Io(ref io_err) => Some(io_err as &error::Error),
impl Error for ZipError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
ZipError::Io(err) => Some(err),
_ => None,
}
}
}
impl ZipError {
/// The text used as an error when a password is required and not supplied
///
/// ```rust,no_run
/// # use zip::result::ZipError;
/// # let mut archive = zip::ZipArchive::new(std::io::Cursor::new(&[])).unwrap();
/// match archive.by_index(1) {
/// Err(ZipError::UnsupportedArchive(ZipError::PASSWORD_REQUIRED)) => eprintln!("a password is needed to unzip this file"),
/// _ => (),
/// }
/// # ()
/// ```
pub const PASSWORD_REQUIRED: &'static str = "Password required to decrypt file";
}
impl From<ZipError> for io::Error {
fn from(err: ZipError) -> io::Error {
io::Error::new(io::ErrorKind::Other, err)
}
}

247
third_party/rust/zip/src/spec.rs поставляемый
Просмотреть файл

@ -1,16 +1,18 @@
use crate::result::{ZipError, ZipResult};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io;
use std::io::prelude::*;
use result::{ZipResult, ZipError};
use podio::{ReadPodExt, WritePodExt, LittleEndian};
pub const LOCAL_FILE_HEADER_SIGNATURE : u32 = 0x04034b50;
pub const CENTRAL_DIRECTORY_HEADER_SIGNATURE : u32 = 0x02014b50;
const CENTRAL_DIRECTORY_END_SIGNATURE : u32 = 0x06054b50;
pub const ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE : u32 = 0x06064b50;
const ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE : u32 = 0x07064b50;
pub const LOCAL_FILE_HEADER_SIGNATURE: u32 = 0x04034b50;
pub const CENTRAL_DIRECTORY_HEADER_SIGNATURE: u32 = 0x02014b50;
const CENTRAL_DIRECTORY_END_SIGNATURE: u32 = 0x06054b50;
pub const ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE: u32 = 0x06064b50;
const ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE: u32 = 0x07064b50;
pub struct CentralDirectoryEnd
{
pub const ZIP64_BYTES_THR: u64 = u32::MAX as u64;
pub const ZIP64_ENTRY_THR: usize = u16::MAX as usize;
pub struct CentralDirectoryEnd {
pub disk_number: u16,
pub disk_with_central_directory: u16,
pub number_of_files_on_this_disk: u16,
@ -20,116 +22,115 @@ pub struct CentralDirectoryEnd
pub zip_file_comment: Vec<u8>,
}
impl CentralDirectoryEnd
{
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd>
{
let magic = try!(reader.read_u32::<LittleEndian>());
if magic != CENTRAL_DIRECTORY_END_SIGNATURE
{
return Err(ZipError::InvalidArchive("Invalid digital signature header"))
impl CentralDirectoryEnd {
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> {
let magic = reader.read_u32::<LittleEndian>()?;
if magic != CENTRAL_DIRECTORY_END_SIGNATURE {
return Err(ZipError::InvalidArchive("Invalid digital signature header"));
}
let disk_number = try!(reader.read_u16::<LittleEndian>());
let disk_with_central_directory = try!(reader.read_u16::<LittleEndian>());
let number_of_files_on_this_disk = try!(reader.read_u16::<LittleEndian>());
let number_of_files = try!(reader.read_u16::<LittleEndian>());
let central_directory_size = try!(reader.read_u32::<LittleEndian>());
let central_directory_offset = try!(reader.read_u32::<LittleEndian>());
let zip_file_comment_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let zip_file_comment = try!(ReadPodExt::read_exact(reader, zip_file_comment_length));
let disk_number = reader.read_u16::<LittleEndian>()?;
let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
let number_of_files = reader.read_u16::<LittleEndian>()?;
let central_directory_size = reader.read_u32::<LittleEndian>()?;
let central_directory_offset = reader.read_u32::<LittleEndian>()?;
let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
let mut zip_file_comment = vec![0; zip_file_comment_length];
reader.read_exact(&mut zip_file_comment)?;
Ok(CentralDirectoryEnd
{
disk_number: disk_number,
disk_with_central_directory: disk_with_central_directory,
number_of_files_on_this_disk: number_of_files_on_this_disk,
number_of_files: number_of_files,
central_directory_size: central_directory_size,
central_directory_offset: central_directory_offset,
zip_file_comment: zip_file_comment,
})
Ok(CentralDirectoryEnd {
disk_number,
disk_with_central_directory,
number_of_files_on_this_disk,
number_of_files,
central_directory_size,
central_directory_offset,
zip_file_comment,
})
}
pub fn find_and_parse<T: Read+io::Seek>(reader: &mut T) -> ZipResult<(CentralDirectoryEnd, u64)>
{
pub fn find_and_parse<T: Read + io::Seek>(
reader: &mut T,
) -> ZipResult<(CentralDirectoryEnd, u64)> {
const HEADER_SIZE: u64 = 22;
const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6;
let file_length = try!(reader.seek(io::SeekFrom::End(0)));
let file_length = reader.seek(io::SeekFrom::End(0))?;
let search_upper_bound = file_length.checked_sub(HEADER_SIZE + ::std::u16::MAX as u64).unwrap_or(0);
let search_upper_bound = file_length.saturating_sub(HEADER_SIZE + ::std::u16::MAX as u64);
if file_length < HEADER_SIZE {
return Err(ZipError::InvalidArchive("Invalid zip header"));
}
let mut pos = file_length - HEADER_SIZE;
while pos >= search_upper_bound
{
try!(reader.seek(io::SeekFrom::Start(pos as u64)));
if try!(reader.read_u32::<LittleEndian>()) == CENTRAL_DIRECTORY_END_SIGNATURE
{
try!(reader.seek(io::SeekFrom::Current(BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64)));
let comment_length = try!(reader.read_u16::<LittleEndian>()) as u64;
if file_length - pos - HEADER_SIZE == comment_length
{
let cde_start_pos = try!(reader.seek(io::SeekFrom::Start(pos as u64)));
return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
}
while pos >= search_upper_bound {
reader.seek(io::SeekFrom::Start(pos as u64))?;
if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE {
reader.seek(io::SeekFrom::Current(
BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64,
))?;
let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?;
return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
}
pos = match pos.checked_sub(1) {
Some(p) => p,
None => break,
};
}
Err(ZipError::InvalidArchive("Could not find central directory end"))
Err(ZipError::InvalidArchive(
"Could not find central directory end",
))
}
pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()>
{
try!(writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE));
try!(writer.write_u16::<LittleEndian>(self.disk_number));
try!(writer.write_u16::<LittleEndian>(self.disk_with_central_directory));
try!(writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk));
try!(writer.write_u16::<LittleEndian>(self.number_of_files));
try!(writer.write_u32::<LittleEndian>(self.central_directory_size));
try!(writer.write_u32::<LittleEndian>(self.central_directory_offset));
try!(writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16));
try!(writer.write_all(&self.zip_file_comment));
pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()> {
writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE)?;
writer.write_u16::<LittleEndian>(self.disk_number)?;
writer.write_u16::<LittleEndian>(self.disk_with_central_directory)?;
writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk)?;
writer.write_u16::<LittleEndian>(self.number_of_files)?;
writer.write_u32::<LittleEndian>(self.central_directory_size)?;
writer.write_u32::<LittleEndian>(self.central_directory_offset)?;
writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16)?;
writer.write_all(&self.zip_file_comment)?;
Ok(())
}
}
pub struct Zip64CentralDirectoryEndLocator
{
pub struct Zip64CentralDirectoryEndLocator {
pub disk_with_central_directory: u32,
pub end_of_central_directory_offset: u64,
pub number_of_disks: u32,
}
impl Zip64CentralDirectoryEndLocator
{
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator>
{
let magic = try!(reader.read_u32::<LittleEndian>());
if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE
{
return Err(ZipError::InvalidArchive("Invalid zip64 locator digital signature header"))
impl Zip64CentralDirectoryEndLocator {
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator> {
let magic = reader.read_u32::<LittleEndian>()?;
if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE {
return Err(ZipError::InvalidArchive(
"Invalid zip64 locator digital signature header",
));
}
let disk_with_central_directory = try!(reader.read_u32::<LittleEndian>());
let end_of_central_directory_offset = try!(reader.read_u64::<LittleEndian>());
let number_of_disks = try!(reader.read_u32::<LittleEndian>());
let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
let number_of_disks = reader.read_u32::<LittleEndian>()?;
Ok(Zip64CentralDirectoryEndLocator
{
disk_with_central_directory: disk_with_central_directory,
end_of_central_directory_offset: end_of_central_directory_offset,
number_of_disks: number_of_disks,
})
Ok(Zip64CentralDirectoryEndLocator {
disk_with_central_directory,
end_of_central_directory_offset,
number_of_disks,
})
}
pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()> {
writer.write_u32::<LittleEndian>(ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE)?;
writer.write_u32::<LittleEndian>(self.disk_with_central_directory)?;
writer.write_u64::<LittleEndian>(self.end_of_central_directory_offset)?;
writer.write_u32::<LittleEndian>(self.number_of_disks)?;
Ok(())
}
}
pub struct Zip64CentralDirectoryEnd
{
pub struct Zip64CentralDirectoryEnd {
pub version_made_by: u16,
pub version_needed_to_extract: u16,
pub disk_number: u32,
@ -141,50 +142,66 @@ pub struct Zip64CentralDirectoryEnd
//pub extensible_data_sector: Vec<u8>, <-- We don't do anything with this at the moment.
}
impl Zip64CentralDirectoryEnd
{
pub fn find_and_parse<T: Read+io::Seek>(reader: &mut T,
nominal_offset: u64,
search_upper_bound: u64) -> ZipResult<(Zip64CentralDirectoryEnd, u64)>
{
impl Zip64CentralDirectoryEnd {
pub fn find_and_parse<T: Read + io::Seek>(
reader: &mut T,
nominal_offset: u64,
search_upper_bound: u64,
) -> ZipResult<(Zip64CentralDirectoryEnd, u64)> {
let mut pos = nominal_offset;
while pos <= search_upper_bound
{
while pos <= search_upper_bound {
reader.seek(io::SeekFrom::Start(pos))?;
if reader.read_u32::<LittleEndian>()? == ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE
{
if reader.read_u32::<LittleEndian>()? == ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE {
let archive_offset = pos - nominal_offset;
let _record_size = try!(reader.read_u64::<LittleEndian>());
let _record_size = reader.read_u64::<LittleEndian>()?;
// We would use this value if we did anything with the "zip64 extensible data sector".
let version_made_by = try!(reader.read_u16::<LittleEndian>());
let version_needed_to_extract = try!(reader.read_u16::<LittleEndian>());
let disk_number = try!(reader.read_u32::<LittleEndian>());
let disk_with_central_directory = try!(reader.read_u32::<LittleEndian>());
let number_of_files_on_this_disk = try!(reader.read_u64::<LittleEndian>());
let number_of_files = try!(reader.read_u64::<LittleEndian>());
let central_directory_size = try!(reader.read_u64::<LittleEndian>());
let central_directory_offset = try!(reader.read_u64::<LittleEndian>());
let version_made_by = reader.read_u16::<LittleEndian>()?;
let version_needed_to_extract = reader.read_u16::<LittleEndian>()?;
let disk_number = reader.read_u32::<LittleEndian>()?;
let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
let number_of_files_on_this_disk = reader.read_u64::<LittleEndian>()?;
let number_of_files = reader.read_u64::<LittleEndian>()?;
let central_directory_size = reader.read_u64::<LittleEndian>()?;
let central_directory_offset = reader.read_u64::<LittleEndian>()?;
return Ok((Zip64CentralDirectoryEnd
{
version_made_by: version_made_by,
version_needed_to_extract: version_needed_to_extract,
disk_number: disk_number,
disk_with_central_directory: disk_with_central_directory,
number_of_files_on_this_disk: number_of_files_on_this_disk,
number_of_files: number_of_files,
central_directory_size: central_directory_size,
central_directory_offset: central_directory_offset,
}, archive_offset));
return Ok((
Zip64CentralDirectoryEnd {
version_made_by,
version_needed_to_extract,
disk_number,
disk_with_central_directory,
number_of_files_on_this_disk,
number_of_files,
central_directory_size,
central_directory_offset,
},
archive_offset,
));
}
pos += 1;
}
Err(ZipError::InvalidArchive("Could not find ZIP64 central directory end"))
Err(ZipError::InvalidArchive(
"Could not find ZIP64 central directory end",
))
}
pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()> {
writer.write_u32::<LittleEndian>(ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE)?;
writer.write_u64::<LittleEndian>(44)?; // record size
writer.write_u16::<LittleEndian>(self.version_made_by)?;
writer.write_u16::<LittleEndian>(self.version_needed_to_extract)?;
writer.write_u32::<LittleEndian>(self.disk_number)?;
writer.write_u32::<LittleEndian>(self.disk_with_central_directory)?;
writer.write_u64::<LittleEndian>(self.number_of_files_on_this_disk)?;
writer.write_u64::<LittleEndian>(self.number_of_files)?;
writer.write_u64::<LittleEndian>(self.central_directory_size)?;
writer.write_u64::<LittleEndian>(self.central_directory_offset)?;
Ok(())
}
}

485
third_party/rust/zip/src/types.rs поставляемый
Просмотреть файл

@ -1,20 +1,58 @@
//! Types that specify what is contained in a ZIP.
#[cfg(doc)]
use {crate::read::ZipFile, crate::write::FileOptions};
use time;
#[cfg(not(any(
all(target_arch = "arm", target_pointer_width = "32"),
target_arch = "mips",
target_arch = "powerpc"
)))]
use std::sync::atomic;
#[cfg(any(
all(target_arch = "arm", target_pointer_width = "32"),
target_arch = "mips",
target_arch = "powerpc"
))]
mod atomic {
use crossbeam_utils::sync::ShardedLock;
pub use std::sync::atomic::Ordering;
#[derive(Debug, Default)]
pub struct AtomicU64 {
value: ShardedLock<u64>,
}
impl AtomicU64 {
pub fn new(v: u64) -> Self {
Self {
value: ShardedLock::new(v),
}
}
pub fn get_mut(&mut self) -> &mut u64 {
self.value.get_mut().unwrap()
}
pub fn load(&self, _: Ordering) -> u64 {
*self.value.read().unwrap()
}
pub fn store(&self, value: u64, _: Ordering) {
*self.value.write().unwrap() = value;
}
}
}
#[cfg(feature = "time")]
use time::{error::ComponentRange, Date, Month, OffsetDateTime, PrimitiveDateTime, Time};
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum System
{
pub enum System {
Dos = 0,
Unix = 3,
Unknown,
#[doc(hidden)]
__Nonexhaustive,
}
impl System {
pub fn from_u8(system: u8) -> System
{
pub fn from_u8(system: u8) -> System {
use self::System::*;
match system {
@ -25,22 +63,249 @@ impl System {
}
}
/// Representation of a moment in time.
///
/// Zip files use an old format from DOS to store timestamps,
/// with its own set of peculiarities.
/// For example, it has a resolution of 2 seconds!
///
/// A [`DateTime`] can be stored directly in a zipfile with [`FileOptions::last_modified_time`],
/// or read from one with [`ZipFile::last_modified`]
///
/// # Warning
///
/// Because there is no timezone associated with the [`DateTime`], they should ideally only
/// be used for user-facing descriptions. This also means [`DateTime::to_time`] returns an
/// [`OffsetDateTime`] (which is the equivalent of chrono's `NaiveDateTime`).
///
/// Modern zip files store more precise timestamps, which are ignored by [`crate::read::ZipArchive`],
/// so keep in mind that these timestamps are unreliable. [We're working on this](https://github.com/zip-rs/zip/issues/156#issuecomment-652981904).
#[derive(Debug, Clone, Copy)]
pub struct DateTime {
year: u16,
month: u8,
day: u8,
hour: u8,
minute: u8,
second: u8,
}
impl ::std::default::Default for DateTime {
/// Constructs an 'default' datetime of 1980-01-01 00:00:00
fn default() -> DateTime {
DateTime {
year: 1980,
month: 1,
day: 1,
hour: 0,
minute: 0,
second: 0,
}
}
}
impl DateTime {
/// Converts an msdos (u16, u16) pair to a DateTime object
pub fn from_msdos(datepart: u16, timepart: u16) -> DateTime {
let seconds = (timepart & 0b0000000000011111) << 1;
let minutes = (timepart & 0b0000011111100000) >> 5;
let hours = (timepart & 0b1111100000000000) >> 11;
let days = datepart & 0b0000000000011111;
let months = (datepart & 0b0000000111100000) >> 5;
let years = (datepart & 0b1111111000000000) >> 9;
DateTime {
year: (years + 1980) as u16,
month: months as u8,
day: days as u8,
hour: hours as u8,
minute: minutes as u8,
second: seconds as u8,
}
}
/// Constructs a DateTime from a specific date and time
///
/// The bounds are:
/// * year: [1980, 2107]
/// * month: [1, 12]
/// * day: [1, 31]
/// * hour: [0, 23]
/// * minute: [0, 59]
/// * second: [0, 60]
#[allow(clippy::result_unit_err)]
pub fn from_date_and_time(
year: u16,
month: u8,
day: u8,
hour: u8,
minute: u8,
second: u8,
) -> Result<DateTime, ()> {
if (1980..=2107).contains(&year)
&& month >= 1
&& month <= 12
&& day >= 1
&& day <= 31
&& hour <= 23
&& minute <= 59
&& second <= 60
{
Ok(DateTime {
year,
month,
day,
hour,
minute,
second,
})
} else {
Err(())
}
}
#[cfg(feature = "time")]
/// Converts a OffsetDateTime object to a DateTime
///
/// Returns `Err` when this object is out of bounds
#[allow(clippy::result_unit_err)]
pub fn from_time(dt: OffsetDateTime) -> Result<DateTime, ()> {
if dt.year() >= 1980 && dt.year() <= 2107 {
Ok(DateTime {
year: (dt.year()) as u16,
month: (dt.month()) as u8,
day: dt.day() as u8,
hour: dt.hour() as u8,
minute: dt.minute() as u8,
second: dt.second() as u8,
})
} else {
Err(())
}
}
/// Gets the time portion of this datetime in the msdos representation
pub fn timepart(&self) -> u16 {
((self.second as u16) >> 1) | ((self.minute as u16) << 5) | ((self.hour as u16) << 11)
}
/// Gets the date portion of this datetime in the msdos representation
pub fn datepart(&self) -> u16 {
(self.day as u16) | ((self.month as u16) << 5) | ((self.year - 1980) << 9)
}
#[cfg(feature = "time")]
/// Converts the DateTime to a OffsetDateTime structure
pub fn to_time(&self) -> Result<OffsetDateTime, ComponentRange> {
use std::convert::TryFrom;
let date =
Date::from_calendar_date(self.year as i32, Month::try_from(self.month)?, self.day)?;
let time = Time::from_hms(self.hour, self.minute, self.second)?;
Ok(PrimitiveDateTime::new(date, time).assume_utc())
}
/// Get the year. There is no epoch, i.e. 2018 will be returned as 2018.
pub fn year(&self) -> u16 {
self.year
}
/// Get the month, where 1 = january and 12 = december
///
/// # Warning
///
/// When read from a zip file, this may not be a reasonable value
pub fn month(&self) -> u8 {
self.month
}
/// Get the day
///
/// # Warning
///
/// When read from a zip file, this may not be a reasonable value
pub fn day(&self) -> u8 {
self.day
}
/// Get the hour
///
/// # Warning
///
/// When read from a zip file, this may not be a reasonable value
pub fn hour(&self) -> u8 {
self.hour
}
/// Get the minute
///
/// # Warning
///
/// When read from a zip file, this may not be a reasonable value
pub fn minute(&self) -> u8 {
self.minute
}
/// Get the second
///
/// # Warning
///
/// When read from a zip file, this may not be a reasonable value
pub fn second(&self) -> u8 {
self.second
}
}
pub const DEFAULT_VERSION: u8 = 46;
/// A type like `AtomicU64` except it implements `Clone` and has predefined
/// ordering.
///
/// It uses `Relaxed` ordering because it is not used for synchronisation.
#[derive(Debug)]
pub struct AtomicU64(atomic::AtomicU64);
impl AtomicU64 {
pub fn new(v: u64) -> Self {
Self(atomic::AtomicU64::new(v))
}
pub fn load(&self) -> u64 {
self.0.load(atomic::Ordering::Relaxed)
}
pub fn store(&self, val: u64) {
self.0.store(val, atomic::Ordering::Relaxed)
}
pub fn get_mut(&mut self) -> &mut u64 {
self.0.get_mut()
}
}
impl Clone for AtomicU64 {
fn clone(&self) -> Self {
Self(atomic::AtomicU64::new(self.load()))
}
}
/// Structure representing a ZIP file.
#[derive(Debug, Clone)]
pub struct ZipFileData
{
pub struct ZipFileData {
/// Compatibility of the file attribute information
pub system: System,
/// Specification version
pub version_made_by: u8,
/// True if the file is encrypted.
pub encrypted: bool,
/// True if the file uses a data-descriptor section
pub using_data_descriptor: bool,
/// Compression method used to store the file
pub compression_method: ::compression::CompressionMethod,
pub compression_method: crate::compression::CompressionMethod,
/// Compression level to store the file
pub compression_level: Option<i32>,
/// Last modified time. This will only have a 2 second precision.
pub last_modified_time: time::Tm,
pub last_modified_time: DateTime,
/// CRC32 checksum
pub crc32: u32,
/// Size of the file in the ZIP
@ -51,14 +316,24 @@ pub struct ZipFileData
pub file_name: String,
/// Raw file name. To be used when file_name was incorrectly decoded.
pub file_name_raw: Vec<u8>,
/// Extra field usually used for storage expansion
pub extra_field: Vec<u8>,
/// File comment
pub file_comment: String,
/// Specifies where the local header of the file starts
pub header_start: u64,
/// Specifies where the central header of the file starts
///
/// Note that when this is not known, it is set to 0
pub central_header_start: u64,
/// Specifies where the compressed data of the file starts
pub data_start: u64,
pub data_start: AtomicU64,
/// External file attributes
pub external_attributes: u32,
/// Reserve local ZIP64 extra field
pub large_file: bool,
/// AES mode if applicable
pub aes_mode: Option<(AesMode, AesVendorVersion)>,
}
impl ZipFileData {
@ -66,7 +341,8 @@ impl ZipFileData {
let no_null_filename = match self.file_name.find('\0') {
Some(index) => &self.file_name[0..index],
None => &self.file_name,
}.to_string();
}
.to_string();
// zip files can contain both / and \ as separators regardless of the OS
// and as we want to return a sanitized PathBuf that only supports the
@ -74,32 +350,70 @@ impl ZipFileData {
let separator = ::std::path::MAIN_SEPARATOR;
let opposite_separator = match separator {
'/' => '\\',
'\\' | _ => '/',
_ => '/',
};
let filename =
no_null_filename.replace(&opposite_separator.to_string(), &separator.to_string());
::std::path::Path::new(&filename)
.components()
.filter(|component| match *component {
::std::path::Component::Normal(..) => true,
_ => false,
})
.filter(|component| matches!(*component, ::std::path::Component::Normal(..)))
.fold(::std::path::PathBuf::new(), |mut path, ref cur| {
path.push(cur.as_os_str());
path
})
}
pub fn zip64_extension(&self) -> bool {
self.uncompressed_size > 0xFFFFFFFF
|| self.compressed_size > 0xFFFFFFFF
|| self.header_start > 0xFFFFFFFF
}
pub fn version_needed(&self) -> u16 {
match self.compression_method {
// higher versions matched first
match (self.zip64_extension(), self.compression_method) {
#[cfg(feature = "bzip2")]
::compression::CompressionMethod::Bzip2 => 46,
(_, crate::compression::CompressionMethod::Bzip2) => 46,
(true, _) => 45,
_ => 20,
}
}
}
/// The encryption specification used to encrypt a file with AES.
///
/// According to the [specification](https://www.winzip.com/win/en/aes_info.html#winzip11) AE-2
/// does not make use of the CRC check.
#[derive(Copy, Clone, Debug)]
pub enum AesVendorVersion {
Ae1,
Ae2,
}
/// AES variant used.
#[derive(Copy, Clone, Debug)]
pub enum AesMode {
Aes128,
Aes192,
Aes256,
}
#[cfg(feature = "aes-crypto")]
impl AesMode {
pub fn salt_length(&self) -> usize {
self.key_length() / 2
}
pub fn key_length(&self) -> usize {
match self {
Self::Aes128 => 16,
Self::Aes192 => 24,
Self::Aes256 => 32,
}
}
}
#[cfg(test)]
mod test {
#[test]
@ -119,18 +433,141 @@ mod test {
system: System::Dos,
version_made_by: 0,
encrypted: false,
compression_method: ::compression::CompressionMethod::Stored,
last_modified_time: time::empty_tm(),
using_data_descriptor: false,
compression_method: crate::compression::CompressionMethod::Stored,
compression_level: None,
last_modified_time: DateTime::default(),
crc32: 0,
compressed_size: 0,
uncompressed_size: 0,
file_name: file_name.clone(),
file_name_raw: file_name.into_bytes(),
extra_field: Vec::new(),
file_comment: String::new(),
header_start: 0,
data_start: 0,
data_start: AtomicU64::new(0),
central_header_start: 0,
external_attributes: 0,
large_file: false,
aes_mode: None,
};
assert_eq!(data.file_name_sanitized(), ::std::path::PathBuf::from("path/etc/passwd"));
assert_eq!(
data.file_name_sanitized(),
::std::path::PathBuf::from("path/etc/passwd")
);
}
#[test]
#[allow(clippy::unusual_byte_groupings)]
fn datetime_default() {
use super::DateTime;
let dt = DateTime::default();
assert_eq!(dt.timepart(), 0);
assert_eq!(dt.datepart(), 0b0000000_0001_00001);
}
#[test]
#[allow(clippy::unusual_byte_groupings)]
fn datetime_max() {
use super::DateTime;
let dt = DateTime::from_date_and_time(2107, 12, 31, 23, 59, 60).unwrap();
assert_eq!(dt.timepart(), 0b10111_111011_11110);
assert_eq!(dt.datepart(), 0b1111111_1100_11111);
}
#[test]
fn datetime_bounds() {
use super::DateTime;
assert!(DateTime::from_date_and_time(2000, 1, 1, 23, 59, 60).is_ok());
assert!(DateTime::from_date_and_time(2000, 1, 1, 24, 0, 0).is_err());
assert!(DateTime::from_date_and_time(2000, 1, 1, 0, 60, 0).is_err());
assert!(DateTime::from_date_and_time(2000, 1, 1, 0, 0, 61).is_err());
assert!(DateTime::from_date_and_time(2107, 12, 31, 0, 0, 0).is_ok());
assert!(DateTime::from_date_and_time(1980, 1, 1, 0, 0, 0).is_ok());
assert!(DateTime::from_date_and_time(1979, 1, 1, 0, 0, 0).is_err());
assert!(DateTime::from_date_and_time(1980, 0, 1, 0, 0, 0).is_err());
assert!(DateTime::from_date_and_time(1980, 1, 0, 0, 0, 0).is_err());
assert!(DateTime::from_date_and_time(2108, 12, 31, 0, 0, 0).is_err());
assert!(DateTime::from_date_and_time(2107, 13, 31, 0, 0, 0).is_err());
assert!(DateTime::from_date_and_time(2107, 12, 32, 0, 0, 0).is_err());
}
#[cfg(feature = "time")]
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
#[cfg(feature = "time")]
#[test]
fn datetime_from_time_bounds() {
use super::DateTime;
use time::macros::datetime;
// 1979-12-31 23:59:59
assert!(DateTime::from_time(datetime!(1979-12-31 23:59:59 UTC)).is_err());
// 1980-01-01 00:00:00
assert!(DateTime::from_time(datetime!(1980-01-01 00:00:00 UTC)).is_ok());
// 2107-12-31 23:59:59
assert!(DateTime::from_time(datetime!(2107-12-31 23:59:59 UTC)).is_ok());
// 2108-01-01 00:00:00
assert!(DateTime::from_time(datetime!(2108-01-01 00:00:00 UTC)).is_err());
}
#[test]
fn time_conversion() {
use super::DateTime;
let dt = DateTime::from_msdos(0x4D71, 0x54CF);
assert_eq!(dt.year(), 2018);
assert_eq!(dt.month(), 11);
assert_eq!(dt.day(), 17);
assert_eq!(dt.hour(), 10);
assert_eq!(dt.minute(), 38);
assert_eq!(dt.second(), 30);
#[cfg(feature = "time")]
assert_eq!(
dt.to_time().unwrap().format(&Rfc3339).unwrap(),
"2018-11-17T10:38:30Z"
);
}
#[test]
fn time_out_of_bounds() {
use super::DateTime;
let dt = DateTime::from_msdos(0xFFFF, 0xFFFF);
assert_eq!(dt.year(), 2107);
assert_eq!(dt.month(), 15);
assert_eq!(dt.day(), 31);
assert_eq!(dt.hour(), 31);
assert_eq!(dt.minute(), 63);
assert_eq!(dt.second(), 62);
#[cfg(feature = "time")]
assert!(dt.to_time().is_err());
let dt = DateTime::from_msdos(0x0000, 0x0000);
assert_eq!(dt.year(), 1980);
assert_eq!(dt.month(), 0);
assert_eq!(dt.day(), 0);
assert_eq!(dt.hour(), 0);
assert_eq!(dt.minute(), 0);
assert_eq!(dt.second(), 0);
#[cfg(feature = "time")]
assert!(dt.to_time().is_err());
}
#[cfg(feature = "time")]
#[test]
fn time_at_january() {
use super::DateTime;
// 2020-01-01 00:00:00
let clock = OffsetDateTime::from_unix_timestamp(1_577_836_800).unwrap();
assert!(DateTime::from_time(clock).is_ok());
}
}

1353
third_party/rust/zip/src/write.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

184
third_party/rust/zip/src/zipcrypto.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,184 @@
//! Implementation of the ZipCrypto algorithm
//!
//! The following paper was used to implement the ZipCrypto algorithm:
//! [https://courses.cs.ut.ee/MTAT.07.022/2015_fall/uploads/Main/dmitri-report-f15-16.pdf](https://courses.cs.ut.ee/MTAT.07.022/2015_fall/uploads/Main/dmitri-report-f15-16.pdf)
use std::num::Wrapping;
/// A container to hold the current key state
struct ZipCryptoKeys {
key_0: Wrapping<u32>,
key_1: Wrapping<u32>,
key_2: Wrapping<u32>,
}
impl ZipCryptoKeys {
fn new() -> ZipCryptoKeys {
ZipCryptoKeys {
key_0: Wrapping(0x12345678),
key_1: Wrapping(0x23456789),
key_2: Wrapping(0x34567890),
}
}
fn update(&mut self, input: u8) {
self.key_0 = ZipCryptoKeys::crc32(self.key_0, input);
self.key_1 =
(self.key_1 + (self.key_0 & Wrapping(0xff))) * Wrapping(0x08088405) + Wrapping(1);
self.key_2 = ZipCryptoKeys::crc32(self.key_2, (self.key_1 >> 24).0 as u8);
}
fn stream_byte(&mut self) -> u8 {
let temp: Wrapping<u16> = Wrapping(self.key_2.0 as u16) | Wrapping(3);
((temp * (temp ^ Wrapping(1))) >> 8).0 as u8
}
fn decrypt_byte(&mut self, cipher_byte: u8) -> u8 {
let plain_byte: u8 = self.stream_byte() ^ cipher_byte;
self.update(plain_byte);
plain_byte
}
#[allow(dead_code)]
fn encrypt_byte(&mut self, plain_byte: u8) -> u8 {
let cipher_byte: u8 = self.stream_byte() ^ plain_byte;
self.update(plain_byte);
cipher_byte
}
fn crc32(crc: Wrapping<u32>, input: u8) -> Wrapping<u32> {
(crc >> 8) ^ Wrapping(CRCTABLE[((crc & Wrapping(0xff)).0 as u8 ^ input) as usize])
}
}
/// A ZipCrypto reader with unverified password
pub struct ZipCryptoReader<R> {
file: R,
keys: ZipCryptoKeys,
}
pub enum ZipCryptoValidator {
PkzipCrc32(u32),
InfoZipMsdosTime(u16),
}
impl<R: std::io::Read> ZipCryptoReader<R> {
/// Note: The password is `&[u8]` and not `&str` because the
/// [zip specification](https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.3.TXT)
/// does not specify password encoding (see function `update_keys` in the specification).
/// Therefore, if `&str` was used, the password would be UTF-8 and it
/// 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 {
file,
keys: ZipCryptoKeys::new(),
};
// Key the cipher by updating the keys with the password.
for byte in password.iter() {
result.keys.update(*byte);
}
result
}
/// Read the ZipCrypto header bytes and validate the password.
pub fn validate(
mut self,
validator: ZipCryptoValidator,
) -> Result<Option<ZipCryptoReaderValid<R>>, std::io::Error> {
// ZipCrypto prefixes a file with a 12 byte header
let mut header_buf = [0u8; 12];
self.file.read_exact(&mut header_buf)?;
for byte in header_buf.iter_mut() {
*byte = self.keys.decrypt_byte(*byte);
}
match validator {
ZipCryptoValidator::PkzipCrc32(crc32_plaintext) => {
// PKZIP before 2.0 used 2 byte CRC check.
// PKZIP 2.0+ used 1 byte CRC check. It's more secure.
// We also use 1 byte CRC.
if (crc32_plaintext >> 24) as u8 != header_buf[11] {
return Ok(None); // Wrong password
}
}
ZipCryptoValidator::InfoZipMsdosTime(last_mod_time) => {
// Info-ZIP modification to ZipCrypto format:
// If bit 3 of the general purpose bit flag is set
// (indicates that the file uses a data-descriptor section),
// it uses high byte of 16-bit File Time.
// Info-ZIP code probably writes 2 bytes of File Time.
// We check only 1 byte.
if (last_mod_time >> 8) as u8 != header_buf[11] {
return Ok(None); // Wrong password
}
}
}
Ok(Some(ZipCryptoReaderValid { reader: self }))
}
}
/// A ZipCrypto reader with verified password
pub struct ZipCryptoReaderValid<R> {
reader: ZipCryptoReader<R>,
}
impl<R: std::io::Read> std::io::Read for ZipCryptoReaderValid<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
// Note: There might be potential for optimization. Inspiration can be found at:
// https://github.com/kornelski/7z/blob/master/CPP/7zip/Crypto/ZipCrypto.cpp
let result = self.reader.file.read(buf);
for byte in buf.iter_mut() {
*byte = self.reader.keys.decrypt_byte(*byte);
}
result
}
}
impl<R: std::io::Read> ZipCryptoReaderValid<R> {
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.reader.file
}
}
static CRCTABLE: [u32; 256] = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
];

80
third_party/rust/zip/tests/aes_encryption.rs поставляемый Normal file
Просмотреть файл

@ -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);
}

Двоичные данные
third_party/rust/zip/tests/data/aes_archive.zip поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
third_party/rust/zip/tests/data/comment_garbage.zip поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
third_party/rust/zip/tests/data/files_and_dirs.zip поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
third_party/rust/zip/tests/data/invalid_offset2.zip поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
third_party/rust/zip/tests/data/mimetype.zip поставляемый

Двоичный файл не отображается.

205
third_party/rust/zip/tests/end_to_end.rs поставляемый Normal file
Просмотреть файл

@ -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 {} compression", method);
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";

41
third_party/rust/zip/tests/invalid_date.rs поставляемый
Просмотреть файл

@ -1,31 +1,24 @@
extern crate zip;
use zip::read::ZipArchive;
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
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 main() {
fn invalid_date() {
let _archive = ZipArchive::new(Cursor::new(BUF)).unwrap();
}

31
third_party/rust/zip/tests/issue_234.rs поставляемый Normal file
Просмотреть файл

@ -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),
}
}

211
third_party/rust/zip/tests/zip64_large.rs поставляемый Normal file
Просмотреть файл

@ -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),
};
}
}

30
third_party/rust/zip/tests/zip_comment_garbage.rs поставляемый Normal file
Просмотреть файл

@ -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());
}

85
third_party/rust/zip/tests/zip_crypto.rs поставляемый Normal file
Просмотреть файл

@ -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());
}
}