This source file includes following definitions.
- message
- setup
- teardown
- pad
- append_member
- list_archive
- START_PARAMETRIZED_TEST
- START_PARAMETRIZED_TEST
- main
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 #define TEST_SUITE_NAME "/src/vfs/cpio"
27
28 #include "tests/mctest.h"
29
30 #include <stdio.h>
31 #include <unistd.h>
32
33 #include "lib/strutil.h"
34 #include "src/vfs/local/local.h"
35
36 #include "src/vfs/cpio/cpio.c"
37
38
39
40 typedef enum
41 {
42 FORMAT_BIN,
43 FORMAT_OLDC,
44 FORMAT_NEWC
45 } archive_format_t;
46
47
48
49
50
51
52 static char *message__text = NULL;
53
54
55 void
56 message (int flags, const char *title, const char *text, ...)
57 {
58 va_list ap;
59
60 (void) flags;
61 (void) title;
62
63 g_free (message__text);
64 va_start (ap, text);
65 message__text = g_strdup_vprintf (text, ap);
66 va_end (ap);
67 }
68
69
70
71
72 static void
73 setup (void)
74 {
75 str_init_strings (NULL);
76
77 vfs_init ();
78 vfs_init_localfs ();
79 vfs_init_cpiofs ();
80 }
81
82
83
84
85 static void
86 teardown (void)
87 {
88 vfs_shut ();
89 str_uninit_strings ();
90
91 MC_PTR_FREE (message__text);
92 }
93
94
95
96 static void
97 pad (GByteArray *archive, guint alignment)
98 {
99 while (archive->len % alignment != 0)
100 g_byte_array_append (archive, (const guint8 *) "", 1);
101 }
102
103
104
105
106 static void
107 append_member (GByteArray *archive, archive_format_t format, const char *name, mode_t mode,
108 guint64 data_size, const char *data, size_t data_len)
109 {
110 const size_t name_size = strlen (name) + 1;
111 char header[128];
112
113 switch (format)
114 {
115 case FORMAT_BIN:
116 {
117
118 const unsigned short h[13] = {
119 070707,
120 0,
121 1,
122 (unsigned short) mode,
123 0,
124 0,
125 1,
126 0,
127 0,
128 0,
129 (unsigned short) name_size,
130 (unsigned short) (data_size >> 16),
131 (unsigned short) (data_size & 0xFFFF),
132 };
133
134 g_byte_array_append (archive, (const guint8 *) h, sizeof (h));
135 g_byte_array_append (archive, (const guint8 *) name, name_size);
136 pad (archive, 2);
137 g_byte_array_append (archive, (const guint8 *) data, data_len);
138 pad (archive, 2);
139 break;
140 }
141 case FORMAT_OLDC:
142 snprintf (header, sizeof (header),
143 "070707"
144 "000000"
145 "000001"
146 "%06o"
147 "000000"
148 "000000"
149 "000001"
150 "000000"
151 "00000000000"
152 "%06o"
153 "%011llo",
154 (unsigned int) mode, (unsigned int) name_size, (unsigned long long) data_size);
155 g_byte_array_append (archive, (const guint8 *) header, strlen (header));
156 g_byte_array_append (archive, (const guint8 *) name, name_size);
157 g_byte_array_append (archive, (const guint8 *) data, data_len);
158 break;
159 case FORMAT_NEWC:
160 snprintf (header, sizeof (header),
161 "070701"
162 "00000001"
163 "%08X"
164 "00000000"
165 "00000000"
166 "00000001"
167 "00000000"
168 "%08llX"
169 "00000000"
170 "00000000"
171 "00000000"
172 "00000000"
173 "%08X"
174 "00000000",
175 (unsigned int) mode, (unsigned long long) data_size, (unsigned int) name_size);
176 g_byte_array_append (archive, (const guint8 *) header, strlen (header));
177 g_byte_array_append (archive, (const guint8 *) name, name_size);
178 pad (archive, 4);
179 g_byte_array_append (archive, (const guint8 *) data, data_len);
180 pad (archive, 4);
181 break;
182 default:
183 g_assert_not_reached ();
184 }
185 }
186
187
188
189
190 static char **
191 list_archive (GByteArray *archive, const char *link_name, char *link_target, size_t target_size)
192 {
193 static const guint8 zero_block[512] = { 0 };
194 char *dir;
195 char *path;
196 char *archive_path;
197 vfs_path_t *vpath;
198 DIR *d;
199 struct vfs_dirent *de;
200 GPtrArray *listing;
201
202
203 g_byte_array_append (archive, zero_block, sizeof (zero_block));
204
205 dir = g_dir_make_tmp ("mctest-XXXXXX", NULL);
206 mctest_assert_not_null (dir);
207 path = g_build_filename (dir, "test.cpio", (char *) NULL);
208 mctest_assert_true (
209 g_file_set_contents (path, (const char *) archive->data, (gssize) archive->len, NULL));
210
211 archive_path = g_strconcat (path, PATH_SEP_STR "ucpio" VFS_PATH_URL_DELIMITER, (char *) NULL);
212 vpath = vfs_path_from_str (archive_path);
213 d = mc_opendir (vpath);
214 mctest_assert_not_null (d);
215
216 listing = g_ptr_array_new ();
217 while ((de = mc_readdir (d)) != NULL)
218 g_ptr_array_add (listing, g_strdup (de->d_name));
219 g_ptr_array_add (listing, NULL);
220 mc_closedir (d);
221
222 if (link_target != NULL)
223 {
224 vfs_path_t *link_vpath;
225 ssize_t len;
226
227 link_vpath = vfs_path_append_new (vpath, link_name, (char *) NULL);
228 len = mc_readlink (link_vpath, link_target, target_size - 1);
229 link_target[MAX (len, 0)] = '\0';
230 vfs_path_free (link_vpath, TRUE);
231 }
232
233 vfs_path_free (vpath, TRUE);
234 g_free (archive_path);
235 unlink (path);
236 g_free (path);
237 rmdir (dir);
238 g_free (dir);
239
240 return (char **) g_ptr_array_free (listing, FALSE);
241 }
242
243
244
245
246 static const struct test_cpio_symlink_size_ds
247 {
248 archive_format_t format;
249 guint64 link_size;
250 } test_cpio_symlink_size_ds[] = {
251
252 { FORMAT_BIN, 0xFFFFFFFF },
253 { FORMAT_NEWC, 0xFFFFFFFF },
254 { FORMAT_OLDC, 077777777777 },
255
256 { FORMAT_BIN, MC_MAXPATHLEN + 1 },
257 { FORMAT_NEWC, MC_MAXPATHLEN + 1 },
258 { FORMAT_OLDC, MC_MAXPATHLEN + 1 },
259 };
260
261
262 START_PARAMETRIZED_TEST (test_cpio_symlink_size, test_cpio_symlink_size_ds)
263 {
264 GByteArray *archive;
265 char *filler;
266 size_t filler_len;
267 char **listing;
268
269
270 archive = g_byte_array_new ();
271 filler_len = MC_MAXPATHLEN + 1;
272 filler = g_strnfill (filler_len, 'x');
273 append_member (archive, data->format, "a", S_IFREG | 0644, 6, "hello\n", 6);
274 append_member (archive, data->format, "link", S_IFLNK | 0777, data->link_size, filler,
275 MIN (filler_len, data->link_size));
276 append_member (archive, data->format, "z", S_IFREG | 0644, 6, "hello\n", 6);
277 append_member (archive, data->format, "TRAILER!!!", 0, 0, "", 0);
278
279
280 listing = list_archive (archive, NULL, NULL, 0);
281
282
283 mctest_assert_not_null (message__text);
284 mctest_assert_true (g_str_has_prefix (message__text, "Corrupted cpio header"));
285 mctest_assert_true (g_strv_contains ((const char *const *) listing, "a"));
286 mctest_assert_false (g_strv_contains ((const char *const *) listing, "link"));
287
288
289 g_strfreev (listing);
290 g_free (filler);
291 g_byte_array_free (archive, TRUE);
292 }
293 END_PARAMETRIZED_TEST
294
295
296
297
298 static const struct test_cpio_symlink_long_target_ds
299 {
300 archive_format_t format;
301 } test_cpio_symlink_long_target_ds[] = {
302 { FORMAT_BIN },
303 { FORMAT_NEWC },
304 { FORMAT_OLDC },
305 };
306
307
308 START_PARAMETRIZED_TEST (test_cpio_symlink_long_target, test_cpio_symlink_long_target_ds)
309 {
310 GByteArray *archive;
311 char *target;
312 char link_target[MC_MAXPATHLEN + 1];
313 char **listing;
314 char *joined;
315
316
317 archive = g_byte_array_new ();
318 target = g_strnfill (2000, 'd');
319 append_member (archive, data->format, "a", S_IFREG | 0644, 6, "hello\n", 6);
320 append_member (archive, data->format, "link", S_IFLNK | 0777, strlen (target), target,
321 strlen (target));
322 append_member (archive, data->format, "z", S_IFREG | 0644, 6, "hello\n", 6);
323 append_member (archive, data->format, "TRAILER!!!", 0, 0, "", 0);
324
325
326 listing = list_archive (archive, "link", link_target, sizeof (link_target));
327
328
329 joined = g_strjoinv (" ", listing);
330 mctest_assert_null (message__text);
331 mctest_assert_str_eq (joined, "a link z");
332 mctest_assert_str_eq (link_target, target);
333
334
335 g_free (joined);
336 g_strfreev (listing);
337 g_free (target);
338 g_byte_array_free (archive, TRUE);
339 }
340 END_PARAMETRIZED_TEST
341
342
343
344 int
345 main (void)
346 {
347 TCase *tc_core;
348
349 tc_core = tcase_create ("Core");
350
351 tcase_add_checked_fixture (tc_core, setup, teardown);
352
353
354 mctest_add_parameterized_test (tc_core, test_cpio_symlink_size, test_cpio_symlink_size_ds);
355 mctest_add_parameterized_test (tc_core, test_cpio_symlink_long_target,
356 test_cpio_symlink_long_target_ds);
357
358
359 return mctest_run_all (tc_core);
360 }
361
362