File: README.md

package info (click to toggle)
rust-coreutils 0.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 505,620 kB
  • sloc: ansic: 103,594; asm: 28,570; sh: 8,910; python: 5,581; makefile: 472; cpp: 97; javascript: 72
file content (143 lines) | stat: -rw-r--r-- 6,869 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# zip [![crates.io version](https://img.shields.io/crates/v/zip)](https://crates.io/crates/zip) ![crates.io downloads](https://img.shields.io/crates/d/zip) [![docs.rs](https://img.shields.io/docsrs/zip)](https://docs.rs/zip) [![Build Status](https://github.com/zip-rs/zip2/actions/workflows/ci.yaml/badge.svg)](https://github.com/zip-rs/zip2/actions?query=branch%3Amaster+workflow%3ACI) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/11847/badge)](https://www.bestpractices.dev/projects/11847)

A zip library for rust which supports reading and writing of simple ZIP files. Currently hosted at
<https://github.com/zip-rs/zip2>.

Supported compression formats:
- Compress and decompress:
  - stored (i.e. none)
  - deflate
  - bzip2
  - zstd
  - xz
  - ppmd
- Decompress only:
  - deflate64
  - lzma
  - implode
  - reduce
  - shrink
Currently unsupported zip extensions:

- Multi-disk

## Features

The features available are:

- `aes-crypto`: Enables decryption of files which were encrypted with AES. Supports AE-1 and AE-2 methods.
- `deflate`: Enables compressing and decompressing an unspecified implementation (that may change in future versions) of
  the deflate compression algorithm, which is the default for zip files. Supports compression quality 1..=264.
- `deflate-flate2`: Combine this with any `flate2` feature flag that enables a back-end, to support deflate compression
  at quality 1..=9.
- `deflate-zopfli`: Enables deflating files with the `zopfli` library (used when compression quality is 10..=264). This
  is the most effective `deflate` implementation available, but also among the slowest. If `flate2` isn't also enabled,
  only compression will be supported and not decompression.
- `deflate64`: Enables the deflate64 compression algorithm. Only decompression is supported.
- `lzma`: Enables the LZMA compression algorithm. Only decompression is supported.
- `bzip2`: Enables the BZip2 compression algorithm.
- `ppmd`: Enables the PPMd compression algorithm.
- `time`: Enables features using the [time](https://github.com/time-rs/time) crate.
- `chrono`: Enables converting last-modified `zip::DateTime` to and from `chrono::NaiveDateTime`.
- `jiff-02`: Enables converting last-modified `zip::DateTime` to and from `jiff::civil::DateTime`.
- `nt-time`: Enables returning timestamps stored in the NTFS extra field as `nt_time::FileTime`.
- `xz`: Enables the XZ compression algorithm.
- `zstd`: Enables the Zstandard compression algorithm.

By default `aes-crypto`, `bzip2`, `deflate`, `deflate64`, `lzma`, `ppmd`, `time`, `xz` and `zstd` are enabled.

## MSRV

Our current Minimum Supported Rust Version is **1.88**. When adding features,
we will follow these guidelines:

- We will always support a minor Rust version that has been stable for at least 6 months.
- Any change to the MSRV will be accompanied with a **minor** version bump.

## Examples

See the [examples directory](examples) for:

- How to [write a file to a zip](./examples/write_sample.rs).
- How to [write a directory of files to a zip](./examples/write_dir.rs) (using [walkdir](https://github.com/BurntSushi/walkdir)).
- How to [extract a zip file](./examples/extract.rs).
- How to [extract a single file from a zip](./examples/extract_lorem.rs).
- How to [read a zip from the standard input](./examples/stdin_info.rs).
- How to [append a directory to an existing archive](./examples/append.rs)

## Fuzzing

Fuzzing support is through [`cargo afl`](https://rust-fuzz.github.io/book/afl/tutorial.html). To install `cargo afl`:

```sh
cargo install cargo-afl
```

To start fuzzing zip extraction:

```sh
mkdir -vp fuzz-read-out
cargo afl build --manifest-path=fuzz/Cargo.toml --all-features -p fuzz_read
# Curated input corpus:
cargo afl fuzz -i fuzz/read/in -o fuzz-read-out fuzz/target/debug/fuzz_read
# Test data files:
cargo afl fuzz -i tests/data -e zip -o fuzz-read-out fuzz/target/debug/fuzz_read
```

To start fuzzing zip creation:

```sh
mkdir -vp fuzz-write-out
cargo afl build --manifest-path=fuzz/Cargo.toml --all-features -p fuzz_write
# Curated input corpus and dictionary schema:
cargo afl fuzz -x fuzz/write/fuzz.dict -i fuzz/write/in -o fuzz-write-out fuzz/target/debug/fuzz_write
```

## Fuzzing stdio

The read and write fuzzers can also receive input over stdin for one-off validation. Note here that the fuzzers can be configured to build in support for DEFLATE, or not:

```sh
# Success, no output:
cargo run --manifest-path=fuzz/Cargo.toml --quiet --all-features -p fuzz_read <tests/data/deflate64.zip
# Error, without deflate64 support:
cargo run --manifest-path=fuzz/Cargo.toml --quiet -p fuzz_read <tests/data/deflate64.zip

thread 'main' (537304) panicked at fuzz_read/src/main.rs:40:36:
called `Result::unwrap()` on an `Err` value: UnsupportedArchive("Compression method not supported")
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

The zip creation fuzzer will try to print out a description of the kind of input it translated the input bytes into:

```sh
# This is an empty input case:
<fuzz/write/in/id-000000,time-0,execs-0,orig-0011743621118ab6c5278ffbb8fd14bddd8369ee.min \
  cargo run --manifest-path=fuzz/Cargo.toml --quiet --all-features -p fuzz_write
# This input was translated into one or more test cases:
<fuzz/write/in/id-000000,time-0,execs-0,orig-0011743621118ab6c5278ffbb8fd14bddd8369ee.min \
  cargo run --manifest-path=fuzz/Cargo.toml --quiet -p fuzz_write
writer.start_file_from_path("", FileOptions { compression_method: Stored, compression_level: None, last_modified_time: DateTime::from_date_and_time(2048, 1, 1, 0, 0, 0)?, permissions: None, large_file: false, encrypt_with: None, extended_options: ExtendedFileOptions {extra_data: vec![].into(), central_extra_data: vec![].into()}, alignment: 0 })?;
writer.write_all(&[])?;
writer
let _ = writer.finish_into_readable()?;
```

The zip creation fuzzer uses [`arbitrary::Unstructured`](https://docs.rs/arbitrary/latest/arbitrary/struct.Unstructured.html) to convert bytes over stdin to random inputs, so it can be triggered with other sources of random input:

```sh
# Usually, the random input is translated into zero test cases:
head -c50 /dev/random | cargo run --manifest-path=fuzz/Cargo.toml --quiet --all-features -p fuzz_write
# Sometimes, one or more test cases are generated and successfully evaluated:
head -c50 /dev/random | cargo run --manifest-path=fuzz/Cargo.toml --quiet --all-features -p fuzz_write
writer.set_raw_comment([20, 202])?;
let mut writer = ZipWriter::new_append(writer.finish()?)?;
let sub_writer = {
let mut initial_junk = Cursor::new(vec![106]);
initial_junk.seek(SeekFrom::End(0))?;
                          let mut writer = ZipWriter::new(initial_junk);
writer
};
writer.merge_archive(sub_writer.finish_into_readable()?)?;
let mut writer = ZipWriter::new_append(writer.finish()?)?;
```