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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//! The two builds the zip family can be, and one function per place their
//! behaviour differs.
//!
//! The port follows Info-ZIP Zip 3.0 (July 5th 2008). Apple's build is
//! `zip-33`'s `zip/zip30/` (its patch against upstream is `apple.diff`);
//! Ubuntu's is `3.0-13ubuntu0.2`, which differs from upstream by its build
//! (`BZIP2_SUPPORT` and `UNICODE_SUPPORT` on, `UIDGID_NOT_16BIT`) and a
//! thirteen-patch series. Each difference the code meets is a function
//! here, named for the behaviour, so a call site reads as the C's `#ifdef`
//! did.
//!
//! **Measured, and overriding the spec (the record, `zip-measurements.md`):**
//! Apple writes no 16-bit `Ux` field although its `-v` says `UIDGID_16BIT`
//! (`unix.c` writes it only for a 16-bit `st_uid`): both builds write the
//! same extra fields ([`writes_ux_16bit`] is false for both).
//!
//! **The build (Ubuntu's DEFINES):** `BZIP2_SUPPORT` ([`bzip2_support`]:
//! `cli.rs`'s `-Z`, `zipup.rs`'s `bzfilecompress`, `-v`'s lines,
//! [`last_known_method`]); `UNICODE_SUPPORT` ([`unicode_support`]: the
//! option table, `-v`, [`shows_newline_escaped`], and every site in
//! `unicode.rs`, `readzip.rs` (the central and local names), `zipfile.rs`
//! (putlocal/putcentral), `scan.rs` (`-su`/`-sU`, `-UN escape`, matching by
//! the Unicode name), `fix.rs` (`-FF`), `zipup.rs` (a new entry's UTF-8
//! name)); `UIDGID_NOT_16BIT` ([`writes_ux_16bit`], no effect: neither build
//! writes the field).
//!
//! **The patch series** (`debian/patches/series`, in order):
//!
//! | Patch | Effect | Hook |
//! |---|---|---|
//! | 01 typo "transferring" | `man/zip.1`, `zip.txt` only | none: no binary string changes |
//! | 02 typo "privileges" | man page only | none |
//! | 03 man pages in section 1 | man page only | none |
//! | 04 no unwanted CFLAGS | build flags (`-O3` dropped) | none: no behaviour |
//! | 05 typo "preceding" | man page only | none |
//! | 06 stack markings in i386 assembly | `crc_i386.S`, `match.S` (x86 only) | none: no behaviour |
//! | 07 `fclose(in_file)`, not `fclose(x)` | zipnote `-w` works (Apple's fails: closes the temp's stream) | none: both flavours take 07 (deviation 26, ruling Z4) |
//! | 08 `printf("%s", text)` | help/licence texts have no `%`: same output | none |
//! | 09 `LDFLAGS` | build only | none |
//! | 10 no build date | `-v`'s `Compiled with gcc 13.3.0 for Unix (Linux ELF).` has no date | [`version_post`] (the recorded text) |
//! | 11 typo "ambiguities" | man page only | none |
//! | 12 `mbstowcs(..., wsize + 1)` | without it glibc's fortify aborts on any non-ASCII name | none: the defined, patched behaviour is the only one (`unicode::local_to_wide`; deviation 28, `ub_rulings`) |
//! | 13 `-TT` buffer `+ 4` | without it one byte is written past the command | none: stuffr builds the command as a string (`-TT` in `zip.c:check_zipfile`'s port; deviation 28, `ub_rulings`) |
//!
//! Every Ubuntu row is compared with the reference by
//! `compat_zip_ubuntu::ubuntu_build_rows` (Docker) and the shared table.
//!
//! Hooks used by the front end: [`bzip2_support`], [`unicode_support`],
//! [`help2_brace_line`], [`tt_replaces_braces`], [`test_through_shell`],
//! [`shows_newline_escaped`], [`last_known_method`],
//! [`stale_errno_after_warning`], [`fnmax`], [`origin`], [`version_pre`],
//! [`version_post`].
/// Which reference the family behaves as.
/// `-DBZIP2_SUPPORT`, Ubuntu only: `-Z bzip2` (`-Z b`) is accepted and
/// means method 12, the `-Z` complaint lists `bzip2`, and `-v` has the
/// `BZIP2_SUPPORT` lines. Apple's build has none: `-Z bzip2` is exit 19
/// ("Compression method bzip2 not enabled").
pub
/// `-DUNICODE_SUPPORT`, Ubuntu only: the option table gains `-su`, `-sU`
/// and `-UN` (`unicode`), `-v` has the `UNICODE_SUPPORT` line, names get
/// the UTF-8 flag or the Unicode path field (`unicode.rs`), and a newline
/// in a name is shown as `^J`. Apple's table has none of the three
/// options: `-su` is `-s u` (a bad size), `--show-unicode` is not
/// supported.
pub
/// Whether the 16-bit `Ux` extra field is written: neither build writes it
/// (ruling Z3, measured: the field appears only for a 16-bit `st_uid`). For
/// Task 6, which writes the extra fields.
pub
/// apple.diff (zip.c:925): Apple comments out the `In cmd, {} replaced by
/// temp archive path, else temp appended.` line of `-h2`; Ubuntu keeps it
/// (and its `-TT` replaces the first `{}`, see [`tt_replaces_braces`]).
pub
/// `-TT cmd` under Ubuntu is run through `system("cmd 'temp'")` with the
/// first `{}` replaced by the quoted temp path; under Apple (apple.diff,
/// zip.c:1425) it is `posix_spawnp` of `cmd` as ONE program name with argv
/// `[cmd, temp]`, and a `{}` is refused (`ZE_PARMS`, exit 16).
pub
/// Ubuntu shows a newline in an entry name as `^J` in its messages (its
/// `UNICODE_SUPPORT` display path); Apple shows it raw.
pub
/// zip.h:LAST_KNOWN_COMPMETHOD, which `-v`'s `zipoddities` compares an
/// entry's method with: BZIP2 (12) with Ubuntu's `BZIP2_SUPPORT`, DEFLATE
/// (8) for Apple.
pub
/// `-T` (zip.c:check_zipfile): Apple runs `unzip` and a `-TT` command with
/// `posix_spawnp` (no shell; `{}` refused), Ubuntu through `system()`
/// (`/bin/sh -c`, the temp path quoted, `{}` replaced). Same as
/// [`tt_replaces_braces`].
pub
/// zip.c:main, `-MM` and an input that could not be opened: Ubuntu's
/// `zip I/O error:` line says `Invalid argument`, the `errno` glibc's
/// stdio leaves after the warnings before it; Apple's says why the open
/// failed (measured, the record's code table, exit 18).
pub
/// tailor.h:FNMAX (`PATH_MAX`): macOS's 1024, glibc's 4096. The split
/// prompts read lines of this size (`fgets(buf, FNMAX, stdin)` for `-sp`,
/// `FNMAX + 4010` when asking where a part to read is), so a longer answer
/// is read in pieces, each its own answer.
pub
/// Where the reference came from, for the banner: stuffr's banner line is
/// the reference's, by stuffr, marked as altered (Info-ZIP licence clause
/// 3), and says whose build it alters.
pub
/// The preamble of `-v` for `name`, flavour `f`: the recorded text before
/// the banner line.
pub
/// What follows the banner line of `-v` for `name`, flavour `f`.
pub