]> git.proxmox.com Git - rustc.git/blame - vendor/tar/tests/header/mod.rs
New upstream version 1.47.0~beta.2+dfsg1
[rustc.git] / vendor / tar / tests / header / mod.rs
CommitLineData
7cac9316
XL
1use std::fs::{self, File};
2use std::io::{self, Write};
3use std::path::Path;
ff7c6d11 4use std::{iter, mem, thread, time};
7cac9316 5
3dfed10e 6use tempfile::Builder;
7cac9316 7
a1dfa0c6 8use tar::{GnuHeader, Header, HeaderMode};
7cac9316
XL
9
10#[test]
11fn default_gnu() {
12 let mut h = Header::new_gnu();
13 assert!(h.as_gnu().is_some());
14 assert!(h.as_gnu_mut().is_some());
15 assert!(h.as_ustar().is_none());
16 assert!(h.as_ustar_mut().is_none());
17}
18
19#[test]
20fn goto_old() {
21 let mut h = Header::new_old();
22 assert!(h.as_gnu().is_none());
23 assert!(h.as_gnu_mut().is_none());
24 assert!(h.as_ustar().is_none());
25 assert!(h.as_ustar_mut().is_none());
26}
27
28#[test]
29fn goto_ustar() {
30 let mut h = Header::new_ustar();
31 assert!(h.as_gnu().is_none());
32 assert!(h.as_gnu_mut().is_none());
33 assert!(h.as_ustar().is_some());
34 assert!(h.as_ustar_mut().is_some());
35}
36
37#[test]
38fn link_name() {
39 let mut h = Header::new_gnu();
40 t!(h.set_link_name("foo"));
41 assert_eq!(t!(h.link_name()).unwrap().to_str(), Some("foo"));
42 t!(h.set_link_name("../foo"));
43 assert_eq!(t!(h.link_name()).unwrap().to_str(), Some("../foo"));
44 t!(h.set_link_name("foo/bar"));
45 assert_eq!(t!(h.link_name()).unwrap().to_str(), Some("foo/bar"));
46 t!(h.set_link_name("foo\\ba"));
47 if cfg!(windows) {
48 assert_eq!(t!(h.link_name()).unwrap().to_str(), Some("foo/ba"));
49 } else {
50 assert_eq!(t!(h.link_name()).unwrap().to_str(), Some("foo\\ba"));
51 }
52
53 let name = "foo\\bar\0";
54 for (slot, val) in h.as_old_mut().linkname.iter_mut().zip(name.as_bytes()) {
55 *slot = *val;
56 }
57 assert_eq!(t!(h.link_name()).unwrap().to_str(), Some("foo\\bar"));
58
59 assert!(h.set_link_name("\0").is_err());
60}
61
ff7c6d11
XL
62#[test]
63fn mtime() {
64 let h = Header::new_gnu();
65 assert_eq!(t!(h.mtime()), 0);
66
67 let h = Header::new_ustar();
68 assert_eq!(t!(h.mtime()), 0);
69
70 let h = Header::new_old();
71 assert_eq!(t!(h.mtime()), 0);
72}
73
7cac9316
XL
74#[test]
75fn user_and_group_name() {
76 let mut h = Header::new_gnu();
77 t!(h.set_username("foo"));
78 t!(h.set_groupname("bar"));
79 assert_eq!(t!(h.username()), Some("foo"));
80 assert_eq!(t!(h.groupname()), Some("bar"));
81
82 h = Header::new_ustar();
83 t!(h.set_username("foo"));
84 t!(h.set_groupname("bar"));
85 assert_eq!(t!(h.username()), Some("foo"));
86 assert_eq!(t!(h.groupname()), Some("bar"));
87
88 h = Header::new_old();
89 assert_eq!(t!(h.username()), None);
90 assert_eq!(t!(h.groupname()), None);
91 assert!(h.set_username("foo").is_err());
92 assert!(h.set_groupname("foo").is_err());
93}
94
95#[test]
96fn dev_major_minor() {
97 let mut h = Header::new_gnu();
98 t!(h.set_device_major(1));
99 t!(h.set_device_minor(2));
100 assert_eq!(t!(h.device_major()), Some(1));
101 assert_eq!(t!(h.device_minor()), Some(2));
102
103 h = Header::new_ustar();
104 t!(h.set_device_major(1));
105 t!(h.set_device_minor(2));
106 assert_eq!(t!(h.device_major()), Some(1));
107 assert_eq!(t!(h.device_minor()), Some(2));
108
ff7c6d11
XL
109 h.as_ustar_mut().unwrap().dev_minor[0] = 0x7f;
110 h.as_ustar_mut().unwrap().dev_major[0] = 0x7f;
7cac9316
XL
111 assert!(h.device_major().is_err());
112 assert!(h.device_minor().is_err());
113
114 h.as_ustar_mut().unwrap().dev_minor[0] = b'g';
115 h.as_ustar_mut().unwrap().dev_major[0] = b'h';
116 assert!(h.device_major().is_err());
117 assert!(h.device_minor().is_err());
118
119 h = Header::new_old();
120 assert_eq!(t!(h.device_major()), None);
121 assert_eq!(t!(h.device_minor()), None);
122 assert!(h.set_device_major(1).is_err());
123 assert!(h.set_device_minor(1).is_err());
124}
125
126#[test]
127fn set_path() {
128 let mut h = Header::new_gnu();
129 t!(h.set_path("foo"));
130 assert_eq!(t!(h.path()).to_str(), Some("foo"));
131 t!(h.set_path("foo/"));
132 assert_eq!(t!(h.path()).to_str(), Some("foo/"));
133 t!(h.set_path("foo/bar"));
134 assert_eq!(t!(h.path()).to_str(), Some("foo/bar"));
135 t!(h.set_path("foo\\bar"));
136 if cfg!(windows) {
137 assert_eq!(t!(h.path()).to_str(), Some("foo/bar"));
138 } else {
139 assert_eq!(t!(h.path()).to_str(), Some("foo\\bar"));
140 }
141
3dfed10e
XL
142 // set_path documentation explictly states it removes any ".", signfying the
143 // current directory, from the path. This test ensures that documented
144 // beavhior occurs
145 t!(h.set_path("./control"));
146 assert_eq!(t!(h.path()).to_str(), Some("control"));
147
7cac9316
XL
148 let long_name = iter::repeat("foo").take(100).collect::<String>();
149 let medium1 = iter::repeat("foo").take(52).collect::<String>();
150 let medium2 = iter::repeat("fo/").take(52).collect::<String>();
151
152 assert!(h.set_path(&long_name).is_err());
153 assert!(h.set_path(&medium1).is_err());
154 assert!(h.set_path(&medium2).is_err());
155 assert!(h.set_path("\0").is_err());
156
157 h = Header::new_ustar();
158 t!(h.set_path("foo"));
159 assert_eq!(t!(h.path()).to_str(), Some("foo"));
160
161 assert!(h.set_path(&long_name).is_err());
162 assert!(h.set_path(&medium1).is_err());
163 t!(h.set_path(&medium2));
164 assert_eq!(t!(h.path()).to_str(), Some(&medium2[..]));
165}
166
167#[test]
168fn set_ustar_path_hard() {
169 let mut h = Header::new_ustar();
170 let p = Path::new("a").join(&vec!["a"; 100].join(""));
171 t!(h.set_path(&p));
172 assert_eq!(t!(h.path()), p);
173}
174
175#[test]
176fn set_metadata_deterministic() {
3dfed10e 177 let td = t!(Builder::new().prefix("tar-rs").tempdir());
7cac9316
XL
178 let tmppath = td.path().join("tmpfile");
179
180 fn mk_header(path: &Path, readonly: bool) -> Result<Header, io::Error> {
a1dfa0c6
XL
181 let mut file = t!(File::create(path));
182 t!(file.write_all(b"c"));
183 let mut perms = t!(file.metadata()).permissions();
184 perms.set_readonly(readonly);
185 t!(fs::set_permissions(path, perms));
186 let mut h = Header::new_ustar();
187 h.set_metadata_in_mode(&t!(path.metadata()), HeaderMode::Deterministic);
188 Ok(h)
7cac9316
XL
189 }
190
191 // Create "the same" File twice in a row, one second apart, with differing readonly values.
192 let one = t!(mk_header(tmppath.as_path(), false));
193 thread::sleep(time::Duration::from_millis(1050));
194 let two = t!(mk_header(tmppath.as_path(), true));
195
196 // Always expected to match.
197 assert_eq!(t!(one.size()), t!(two.size()));
198 assert_eq!(t!(one.path()), t!(two.path()));
199 assert_eq!(t!(one.mode()), t!(two.mode()));
200
201 // Would not match without `Deterministic`.
202 assert_eq!(t!(one.mtime()), t!(two.mtime()));
203 // TODO: No great way to validate that these would not be filled, but
204 // check them anyway.
205 assert_eq!(t!(one.uid()), t!(two.uid()));
206 assert_eq!(t!(one.gid()), t!(two.gid()));
207}
ff7c6d11
XL
208
209#[test]
210fn extended_numeric_format() {
211 let mut h: GnuHeader = unsafe { mem::zeroed() };
a1dfa0c6
XL
212 h.as_header_mut().set_size(42);
213 assert_eq!(h.size, [48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 50, 0]);
214 h.as_header_mut().set_size(8589934593);
215 assert_eq!(h.size, [0x80, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, 1]);
ff7c6d11
XL
216 h.size = [0x80, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, 0];
217 assert_eq!(h.as_header().entry_size().unwrap(), 0x0200000000);
a1dfa0c6
XL
218 h.size = [48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 51, 0];
219 assert_eq!(h.as_header().entry_size().unwrap(), 43);
220
221 h.as_header_mut().set_gid(42);
222 assert_eq!(h.gid, [48, 48, 48, 48, 48, 53, 50, 0]);
223 assert_eq!(h.as_header().gid().unwrap(), 42);
224 h.as_header_mut().set_gid(0x7fffffffffffffff);
225 assert_eq!(h.gid, [0xff; 8]);
226 assert_eq!(h.as_header().gid().unwrap(), 0x7fffffffffffffff);
ff7c6d11
XL
227 h.uid = [0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78];
228 assert_eq!(h.as_header().uid().unwrap(), 0x12345678);
a1dfa0c6
XL
229
230 h.mtime = [
231 0x80, 0, 0, 0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
232 ];
ff7c6d11
XL
233 assert_eq!(h.as_header().mtime().unwrap(), 0x0123456789abcdef);
234}
83c7162d
XL
235
236#[test]
237fn byte_slice_conversion() {
238 let h = Header::new_gnu();
239 let b: &[u8] = h.as_bytes();
240 let b_conv: &[u8] = Header::from_byte_slice(h.as_bytes()).as_bytes();
241 assert_eq!(b, b_conv);
242}