1/*-
2 * Copyright (c) 2018 Grzegorz Antoniak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25#include "test.h"
26
27/* Some tests will want to calculate some CRC32's, and this header can
28 * help. */
29#define __LIBARCHIVE_BUILD
30#include <archive_crc32.h>
31#include <archive_endian.h>
32
33#define PROLOGUE(reffile) \
34	struct archive_entry *ae; \
35	struct archive *a; \
36	\
37	(void) a;  /* Make the compiler happy if we won't use this variables */ \
38	(void) ae; /* in the test cases. */ \
39	\
40	extract_reference_file(reffile); \
41	assert((a = archive_read_new()) != NULL); \
42	assertA(0 == archive_read_support_filter_all(a)); \
43	assertA(0 == archive_read_support_format_all(a)); \
44	assertA(0 == archive_read_open_filename(a, reffile, 10240))
45
46#define PROLOGUE_MULTI(reffile) \
47	struct archive_entry *ae; \
48	struct archive *a; \
49	\
50	(void) a; \
51	(void) ae; \
52	\
53	extract_reference_files(reffile); \
54	assert((a = archive_read_new()) != NULL); \
55	assertA(0 == archive_read_support_filter_all(a)); \
56	assertA(0 == archive_read_support_format_all(a)); \
57	assertA(0 == archive_read_open_filenames(a, reffile, 10240))
58
59
60#define EPILOGUE() \
61	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); \
62	assertEqualInt(ARCHIVE_OK, archive_read_free(a))
63
64static
65int verify_data(const uint8_t* data_ptr, int magic, int size) {
66	int i = 0;
67
68	/* This is how the test data inside test files was generated;
69	 * we are re-generating it here and we check if our re-generated
70	 * test data is the same as in the test file. If this test is
71	 * failing it's either because there's a bug in the test case,
72	 * or the unpacked data is corrupted. */
73
74	for(i = 0; i < size / 4; ++i) {
75		const int k = i + 1;
76		const signed int* lptr = (const signed int*) &data_ptr[i * 4];
77		signed int val = k * k - 3 * k + (1 + magic);
78
79		if(val < 0)
80			val = 0;
81
82		/* *lptr is a value inside unpacked test file, val is the
83		 * value that should be in the unpacked test file. */
84
85		if(archive_le32dec(lptr) != (uint32_t) val)
86			return 0;
87	}
88
89	return 1;
90}
91
92static
93int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) {
94	la_ssize_t fsize, bytes_read;
95	uint8_t* buf;
96	int ret = 1;
97	uint32_t computed_crc;
98
99	fsize = (la_ssize_t) archive_entry_size(ae);
100	buf = malloc(fsize);
101	if(buf == NULL)
102		return 1;
103
104	bytes_read = archive_read_data(a, buf, fsize);
105	if(bytes_read != fsize) {
106		assertEqualInt(bytes_read, fsize);
107		goto fn_exit;
108	}
109
110	computed_crc = crc32(0, buf, fsize);
111	assertEqualInt(computed_crc, crc);
112	ret = 0;
113
114fn_exit:
115	free(buf);
116	return ret;
117}
118
119DEFINE_TEST(test_read_format_rar5_set_format)
120{
121	struct archive *a;
122	struct archive_entry *ae;
123	const char reffile[] = "test_read_format_rar5_stored.rar";
124
125	extract_reference_file(reffile);
126	assert((a = archive_read_new()) != NULL);
127	assertA(0 == archive_read_support_filter_all(a));
128	assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR_V5));
129	assertA(0 == archive_read_open_filename(a, reffile, 10240));
130	assertA(0 == archive_read_next_header(a, &ae));
131	EPILOGUE();
132}
133
134DEFINE_TEST(test_read_format_rar5_stored)
135{
136	const char helloworld_txt[] = "hello libarchive test suite!\n";
137	la_ssize_t file_size = sizeof(helloworld_txt) - 1;
138	char buff[64];
139
140	PROLOGUE("test_read_format_rar5_stored.rar");
141
142	assertA(0 == archive_read_next_header(a, &ae));
143	assertEqualString("helloworld.txt", archive_entry_pathname(ae));
144	assertA((int) archive_entry_mtime(ae) > 0);
145	assertA((int) archive_entry_ctime(ae) == 0);
146	assertA((int) archive_entry_atime(ae) == 0);
147	assertEqualInt(file_size, archive_entry_size(ae));
148	assertEqualInt(33188, archive_entry_mode(ae));
149	assertA(file_size == archive_read_data(a, buff, file_size));
150	assertEqualMem(buff, helloworld_txt, file_size);
151	assertEqualInt(archive_entry_is_encrypted(ae), 0);
152
153	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
154
155	EPILOGUE();
156}
157
158DEFINE_TEST(test_read_format_rar5_compressed)
159{
160	const int DATA_SIZE = 1200;
161	uint8_t buff[1200];
162
163	PROLOGUE("test_read_format_rar5_compressed.rar");
164
165	assertA(0 == archive_read_next_header(a, &ae));
166	assertEqualString("test.bin", archive_entry_pathname(ae));
167	assertA((int) archive_entry_mtime(ae) > 0);
168	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
169	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
170	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
171	assertA(1 == verify_data(buff, 0, DATA_SIZE));
172
173	EPILOGUE();
174}
175
176DEFINE_TEST(test_read_format_rar5_multiple_files)
177{
178	const int DATA_SIZE = 4096;
179	uint8_t buff[4096];
180
181	PROLOGUE("test_read_format_rar5_multiple_files.rar");
182
183	/* There should be 4 files inside this test file. Check for their
184	 * existence, and also check the contents of those test files. */
185
186	assertA(0 == archive_read_next_header(a, &ae));
187	assertEqualString("test1.bin", archive_entry_pathname(ae));
188	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
189	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
190	assertA(1 == verify_data(buff, 1, DATA_SIZE));
191
192	assertA(0 == archive_read_next_header(a, &ae));
193	assertEqualString("test2.bin", archive_entry_pathname(ae));
194	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
195	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
196	assertA(1 == verify_data(buff, 2, DATA_SIZE));
197
198	assertA(0 == archive_read_next_header(a, &ae));
199	assertEqualString("test3.bin", archive_entry_pathname(ae));
200	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
201	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
202	assertA(1 == verify_data(buff, 3, DATA_SIZE));
203
204	assertA(0 == archive_read_next_header(a, &ae));
205	assertEqualString("test4.bin", archive_entry_pathname(ae));
206	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
207	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
208	assertA(1 == verify_data(buff, 4, DATA_SIZE));
209
210	/* There should be no more files in this archive. */
211
212	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
213	EPILOGUE();
214}
215
216/* This test is really the same as the test above, but it deals with a solid
217 * archive instead of a regular archive. The test solid archive contains the
218 * same set of files as regular test archive, but it's size is 2x smaller,
219 * because solid archives reuse the window buffer from previous compressed
220 * files, so it's able to compress lots of small files more effectively. */
221
222DEFINE_TEST(test_read_format_rar5_multiple_files_solid)
223{
224	const int DATA_SIZE = 4096;
225	uint8_t buff[4096];
226
227	PROLOGUE("test_read_format_rar5_multiple_files_solid.rar");
228
229	assertA(0 == archive_read_next_header(a, &ae));
230	assertEqualString("test1.bin", archive_entry_pathname(ae));
231	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
232	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
233	assertA(1 == verify_data(buff, 1, DATA_SIZE));
234
235	assertA(0 == archive_read_next_header(a, &ae));
236	assertEqualString("test2.bin", archive_entry_pathname(ae));
237	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
238	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
239	assertA(1 == verify_data(buff, 2, DATA_SIZE));
240
241	assertA(0 == archive_read_next_header(a, &ae));
242	assertEqualString("test3.bin", archive_entry_pathname(ae));
243	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
244	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
245	assertA(1 == verify_data(buff, 3, DATA_SIZE));
246
247	assertA(0 == archive_read_next_header(a, &ae));
248	assertEqualString("test4.bin", archive_entry_pathname(ae));
249	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
250	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
251	assertA(1 == verify_data(buff, 4, DATA_SIZE));
252
253	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
254	EPILOGUE();
255}
256
257DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all)
258{
259	const char* reffiles[] = {
260		"test_read_format_rar5_multiarchive.part01.rar",
261		"test_read_format_rar5_multiarchive.part02.rar",
262		"test_read_format_rar5_multiarchive.part03.rar",
263		"test_read_format_rar5_multiarchive.part04.rar",
264		"test_read_format_rar5_multiarchive.part05.rar",
265		"test_read_format_rar5_multiarchive.part06.rar",
266		"test_read_format_rar5_multiarchive.part07.rar",
267		"test_read_format_rar5_multiarchive.part08.rar",
268		NULL
269	};
270
271	PROLOGUE_MULTI(reffiles);
272	assertA(0 == archive_read_next_header(a, &ae));
273	assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdcat_test", archive_entry_pathname(ae));
274	assertA(0 == archive_read_next_header(a, &ae));
275	assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdtar_test", archive_entry_pathname(ae));
276	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
277	EPILOGUE();
278}
279
280DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_first)
281{
282	const char* reffiles[] = {
283		"test_read_format_rar5_multiarchive.part01.rar",
284		"test_read_format_rar5_multiarchive.part02.rar",
285		"test_read_format_rar5_multiarchive.part03.rar",
286		"test_read_format_rar5_multiarchive.part04.rar",
287		"test_read_format_rar5_multiarchive.part05.rar",
288		"test_read_format_rar5_multiarchive.part06.rar",
289		"test_read_format_rar5_multiarchive.part07.rar",
290		"test_read_format_rar5_multiarchive.part08.rar",
291		NULL
292	};
293
294	PROLOGUE_MULTI(reffiles);
295	assertA(0 == archive_read_next_header(a, &ae));
296	assertA(0 == extract_one(a, ae, 0x35277473));
297	assertA(0 == archive_read_next_header(a, &ae));
298	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
299	EPILOGUE();
300}
301
302DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second)
303{
304	const char* reffiles[] = {
305		"test_read_format_rar5_multiarchive.part01.rar",
306		"test_read_format_rar5_multiarchive.part02.rar",
307		"test_read_format_rar5_multiarchive.part03.rar",
308		"test_read_format_rar5_multiarchive.part04.rar",
309		"test_read_format_rar5_multiarchive.part05.rar",
310		"test_read_format_rar5_multiarchive.part06.rar",
311		"test_read_format_rar5_multiarchive.part07.rar",
312		"test_read_format_rar5_multiarchive.part08.rar",
313		NULL
314	};
315
316	PROLOGUE_MULTI(reffiles);
317	assertA(0 == archive_read_next_header(a, &ae));
318	assertA(0 == archive_read_next_header(a, &ae));
319	assertA(0 == extract_one(a, ae, 0xE59665F8));
320	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
321	EPILOGUE();
322}
323
324DEFINE_TEST(test_read_format_rar5_blake2)
325{
326	const la_ssize_t proper_size = 814;
327	uint8_t buf[814];
328
329	PROLOGUE("test_read_format_rar5_blake2.rar");
330	assertA(0 == archive_read_next_header(a, &ae));
331	assertEqualInt(proper_size, archive_entry_size(ae));
332
333	/* Should blake2 calculation fail, we'll get a failure return
334	 * value from archive_read_data(). */
335
336	assertA(proper_size == archive_read_data(a, buf, proper_size));
337
338	/* To be extra pedantic, let's also check crc32 of the poem. */
339	assertEqualInt(crc32(0, buf, proper_size), 0x7E5EC49E);
340
341	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
342	EPILOGUE();
343}
344
345DEFINE_TEST(test_read_format_rar5_arm_filter)
346{
347	/* This test unpacks a file that uses an ARM filter. The DELTA
348	 * and X86 filters are tested implicitly in the "multiarchive_skip"
349	 * test. */
350
351	const la_ssize_t proper_size = 90808;
352	uint8_t buf[90808];
353
354	PROLOGUE("test_read_format_rar5_arm.rar");
355	assertA(0 == archive_read_next_header(a, &ae));
356	assertEqualInt(proper_size, archive_entry_size(ae));
357	assertA(proper_size == archive_read_data(a, buf, proper_size));
358
359	/* Yes, RARv5 unpacker itself should calculate the CRC, but in case
360	 * the DONT_FAIL_ON_CRC_ERROR define option is enabled during compilation,
361	 * let's still fail the test if the unpacked data is wrong. */
362	assertEqualInt(crc32(0, buf, proper_size), 0x886F91EB);
363
364	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
365	EPILOGUE();
366}
367
368DEFINE_TEST(test_read_format_rar5_stored_skip_all)
369{
370	const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
371
372	PROLOGUE(fname);
373	assertA(0 == archive_read_next_header(a, &ae));
374	assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
375	assertA(0 == archive_read_next_header(a, &ae));
376	assertEqualString("cebula.txt", archive_entry_pathname(ae));
377	assertA(0 == archive_read_next_header(a, &ae));
378	assertEqualString("test.bin", archive_entry_pathname(ae));
379	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
380	EPILOGUE();
381}
382
383DEFINE_TEST(test_read_format_rar5_stored_skip_in_part)
384{
385	const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
386	char buf[6];
387
388	/* Skip first, extract in part rest. */
389
390	PROLOGUE(fname);
391	assertA(0 == archive_read_next_header(a, &ae));
392	assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
393	assertA(0 == archive_read_next_header(a, &ae));
394	assertEqualString("cebula.txt", archive_entry_pathname(ae));
395	assertA(6 == archive_read_data(a, buf, 6));
396	assertEqualInt(0, memcmp(buf, "Cebula", 6));
397	assertA(0 == archive_read_next_header(a, &ae));
398	assertEqualString("test.bin", archive_entry_pathname(ae));
399	assertA(4 == archive_read_data(a, buf, 4));
400	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
401	EPILOGUE();
402}
403
404DEFINE_TEST(test_read_format_rar5_stored_skip_all_but_first)
405{
406	const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
407	char buf[405];
408
409	/* Extract first, skip rest. */
410
411	PROLOGUE(fname);
412	assertA(0 == archive_read_next_header(a, &ae));
413	assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
414	assertA(405 == archive_read_data(a, buf, sizeof(buf)));
415	assertA(0 == archive_read_next_header(a, &ae));
416	assertEqualString("cebula.txt", archive_entry_pathname(ae));
417	assertA(0 == archive_read_next_header(a, &ae));
418	assertEqualString("test.bin", archive_entry_pathname(ae));
419	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
420	EPILOGUE();
421}
422
423DEFINE_TEST(test_read_format_rar5_stored_skip_all_in_part)
424{
425	const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
426	char buf[4];
427
428	/* Extract in part all */
429
430	PROLOGUE(fname);
431	assertA(0 == archive_read_next_header(a, &ae));
432	assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
433	assertA(4 == archive_read_data(a, buf, 4));
434	assertA(0 == archive_read_next_header(a, &ae));
435	assertEqualString("cebula.txt", archive_entry_pathname(ae));
436	assertA(4 == archive_read_data(a, buf, 4));
437	assertA(0 == archive_read_next_header(a, &ae));
438	assertEqualString("test.bin", archive_entry_pathname(ae));
439	assertA(4 == archive_read_data(a, buf, 4));
440	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
441	EPILOGUE();
442}
443
444DEFINE_TEST(test_read_format_rar5_multiarchive_solid_extr_all)
445{
446	const char* reffiles[] = {
447		"test_read_format_rar5_multiarchive_solid.part01.rar",
448		"test_read_format_rar5_multiarchive_solid.part02.rar",
449		"test_read_format_rar5_multiarchive_solid.part03.rar",
450		"test_read_format_rar5_multiarchive_solid.part04.rar",
451		NULL
452	};
453
454	PROLOGUE_MULTI(reffiles);
455	assertA(0 == archive_read_next_header(a, &ae));
456	assertEqualString("cebula.txt", archive_entry_pathname(ae));
457	assertA(0 == extract_one(a, ae, 0x7E5EC49E));
458
459	assertA(0 == archive_read_next_header(a, &ae));
460	assertEqualString("test.bin", archive_entry_pathname(ae));
461	assertA(0 == extract_one(a, ae, 0x7cca70cd));
462
463	assertA(0 == archive_read_next_header(a, &ae));
464	assertEqualString("test1.bin", archive_entry_pathname(ae));
465	assertA(0 == extract_one(a, ae, 0x7e13b2c6));
466
467	assertA(0 == archive_read_next_header(a, &ae));
468	assertEqualString("test2.bin", archive_entry_pathname(ae));
469	assertA(0 == extract_one(a, ae, 0xf166afcb));
470
471	assertA(0 == archive_read_next_header(a, &ae));
472	assertEqualString("test3.bin", archive_entry_pathname(ae));
473	assertA(0 == extract_one(a, ae, 0x9fb123d9));
474
475	assertA(0 == archive_read_next_header(a, &ae));
476	assertEqualString("test4.bin", archive_entry_pathname(ae));
477	assertA(0 == extract_one(a, ae, 0x10c43ed4));
478
479	assertA(0 == archive_read_next_header(a, &ae));
480	assertEqualString("test5.bin", archive_entry_pathname(ae));
481	assertA(0 == extract_one(a, ae, 0xb9d155f2));
482
483	assertA(0 == archive_read_next_header(a, &ae));
484	assertEqualString("test6.bin", archive_entry_pathname(ae));
485	assertA(0 == extract_one(a, ae, 0x36a448ff));
486
487	assertA(0 == archive_read_next_header(a, &ae));
488	assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
489	assertA(0 == extract_one(a, ae, 0x886F91EB));
490
491	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
492	EPILOGUE();
493}
494
495DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all)
496{
497	const char* reffiles[] = {
498		"test_read_format_rar5_multiarchive_solid.part01.rar",
499		"test_read_format_rar5_multiarchive_solid.part02.rar",
500		"test_read_format_rar5_multiarchive_solid.part03.rar",
501		"test_read_format_rar5_multiarchive_solid.part04.rar",
502		NULL
503	};
504
505	PROLOGUE_MULTI(reffiles);
506	assertA(0 == archive_read_next_header(a, &ae));
507	assertEqualString("cebula.txt", archive_entry_pathname(ae));
508	assertA(0 == archive_read_next_header(a, &ae));
509	assertEqualString("test.bin", archive_entry_pathname(ae));
510	assertA(0 == archive_read_next_header(a, &ae));
511	assertEqualString("test1.bin", archive_entry_pathname(ae));
512	assertA(0 == archive_read_next_header(a, &ae));
513	assertEqualString("test2.bin", archive_entry_pathname(ae));
514	assertA(0 == archive_read_next_header(a, &ae));
515	assertEqualString("test3.bin", archive_entry_pathname(ae));
516	assertA(0 == archive_read_next_header(a, &ae));
517	assertEqualString("test4.bin", archive_entry_pathname(ae));
518	assertA(0 == archive_read_next_header(a, &ae));
519	assertEqualString("test5.bin", archive_entry_pathname(ae));
520	assertA(0 == archive_read_next_header(a, &ae));
521	assertEqualString("test6.bin", archive_entry_pathname(ae));
522	assertA(0 == archive_read_next_header(a, &ae));
523	assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
524	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
525	EPILOGUE();
526}
527
528DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_first)
529{
530	const char* reffiles[] = {
531		"test_read_format_rar5_multiarchive_solid.part01.rar",
532		"test_read_format_rar5_multiarchive_solid.part02.rar",
533		"test_read_format_rar5_multiarchive_solid.part03.rar",
534		"test_read_format_rar5_multiarchive_solid.part04.rar",
535		NULL
536	};
537
538	PROLOGUE_MULTI(reffiles);
539	assertA(0 == archive_read_next_header(a, &ae));
540	assertEqualString("cebula.txt", archive_entry_pathname(ae));
541	assertA(0 == extract_one(a, ae, 0x7E5EC49E));
542	assertA(0 == archive_read_next_header(a, &ae));
543	assertEqualString("test.bin", archive_entry_pathname(ae));
544	assertA(0 == archive_read_next_header(a, &ae));
545	assertEqualString("test1.bin", archive_entry_pathname(ae));
546	assertA(0 == archive_read_next_header(a, &ae));
547	assertEqualString("test2.bin", archive_entry_pathname(ae));
548	assertA(0 == archive_read_next_header(a, &ae));
549	assertEqualString("test3.bin", archive_entry_pathname(ae));
550	assertA(0 == archive_read_next_header(a, &ae));
551	assertEqualString("test4.bin", archive_entry_pathname(ae));
552	assertA(0 == archive_read_next_header(a, &ae));
553	assertEqualString("test5.bin", archive_entry_pathname(ae));
554	assertA(0 == archive_read_next_header(a, &ae));
555	assertEqualString("test6.bin", archive_entry_pathname(ae));
556	assertA(0 == archive_read_next_header(a, &ae));
557	assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
558	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
559	EPILOGUE();
560}
561
562/* "skip_all_but_scnd" -> am I hitting the test name limit here after
563 * expansion of "scnd" to "second"? */
564
565DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_scnd)
566{
567	const char* reffiles[] = {
568		"test_read_format_rar5_multiarchive_solid.part01.rar",
569		"test_read_format_rar5_multiarchive_solid.part02.rar",
570		"test_read_format_rar5_multiarchive_solid.part03.rar",
571		"test_read_format_rar5_multiarchive_solid.part04.rar",
572		NULL
573	};
574
575	PROLOGUE_MULTI(reffiles);
576	assertA(0 == archive_read_next_header(a, &ae));
577	assertEqualString("cebula.txt", archive_entry_pathname(ae));
578	assertA(0 == archive_read_next_header(a, &ae));
579	assertEqualString("test.bin", archive_entry_pathname(ae));
580	assertA(0 == extract_one(a, ae, 0x7CCA70CD));
581	assertA(0 == archive_read_next_header(a, &ae));
582	assertEqualString("test1.bin", archive_entry_pathname(ae));
583	assertA(0 == archive_read_next_header(a, &ae));
584	assertEqualString("test2.bin", archive_entry_pathname(ae));
585	assertA(0 == archive_read_next_header(a, &ae));
586	assertEqualString("test3.bin", archive_entry_pathname(ae));
587	assertA(0 == archive_read_next_header(a, &ae));
588	assertEqualString("test4.bin", archive_entry_pathname(ae));
589	assertA(0 == archive_read_next_header(a, &ae));
590	assertEqualString("test5.bin", archive_entry_pathname(ae));
591	assertA(0 == archive_read_next_header(a, &ae));
592	assertEqualString("test6.bin", archive_entry_pathname(ae));
593	assertA(0 == archive_read_next_header(a, &ae));
594	assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
595	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
596	EPILOGUE();
597}
598
599DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_third)
600{
601	const char* reffiles[] = {
602		"test_read_format_rar5_multiarchive_solid.part01.rar",
603		"test_read_format_rar5_multiarchive_solid.part02.rar",
604		"test_read_format_rar5_multiarchive_solid.part03.rar",
605		"test_read_format_rar5_multiarchive_solid.part04.rar",
606		NULL
607	};
608
609	PROLOGUE_MULTI(reffiles);
610	assertA(0 == archive_read_next_header(a, &ae));
611	assertEqualString("cebula.txt", archive_entry_pathname(ae));
612	assertA(0 == archive_read_next_header(a, &ae));
613	assertEqualString("test.bin", archive_entry_pathname(ae));
614	assertA(0 == archive_read_next_header(a, &ae));
615	assertEqualString("test1.bin", archive_entry_pathname(ae));
616	assertA(0 == extract_one(a, ae, 0x7E13B2C6));
617	assertA(0 == archive_read_next_header(a, &ae));
618	assertEqualString("test2.bin", archive_entry_pathname(ae));
619	assertA(0 == archive_read_next_header(a, &ae));
620	assertEqualString("test3.bin", archive_entry_pathname(ae));
621	assertA(0 == archive_read_next_header(a, &ae));
622	assertEqualString("test4.bin", archive_entry_pathname(ae));
623	assertA(0 == archive_read_next_header(a, &ae));
624	assertEqualString("test5.bin", archive_entry_pathname(ae));
625	assertA(0 == archive_read_next_header(a, &ae));
626	assertEqualString("test6.bin", archive_entry_pathname(ae));
627	assertA(0 == archive_read_next_header(a, &ae));
628	assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
629	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
630	EPILOGUE();
631}
632
633DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last)
634{
635	const char* reffiles[] = {
636		"test_read_format_rar5_multiarchive_solid.part01.rar",
637		"test_read_format_rar5_multiarchive_solid.part02.rar",
638		"test_read_format_rar5_multiarchive_solid.part03.rar",
639		"test_read_format_rar5_multiarchive_solid.part04.rar",
640		NULL
641	};
642
643	PROLOGUE_MULTI(reffiles);
644	assertA(0 == archive_read_next_header(a, &ae));
645	assertEqualString("cebula.txt", archive_entry_pathname(ae));
646	assertA(0 == archive_read_next_header(a, &ae));
647	assertEqualString("test.bin", archive_entry_pathname(ae));
648	assertA(0 == archive_read_next_header(a, &ae));
649	assertEqualString("test1.bin", archive_entry_pathname(ae));
650	assertA(0 == archive_read_next_header(a, &ae));
651	assertEqualString("test2.bin", archive_entry_pathname(ae));
652	assertA(0 == archive_read_next_header(a, &ae));
653	assertEqualString("test3.bin", archive_entry_pathname(ae));
654	assertA(0 == archive_read_next_header(a, &ae));
655	assertEqualString("test4.bin", archive_entry_pathname(ae));
656	assertA(0 == archive_read_next_header(a, &ae));
657	assertEqualString("test5.bin", archive_entry_pathname(ae));
658	assertA(0 == archive_read_next_header(a, &ae));
659	assertEqualString("test6.bin", archive_entry_pathname(ae));
660	assertA(0 == archive_read_next_header(a, &ae));
661	assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
662	assertA(0 == extract_one(a, ae, 0x886F91EB));
663	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
664	EPILOGUE();
665}
666
667DEFINE_TEST(test_read_format_rar5_solid_skip_all)
668{
669	const char* reffile = "test_read_format_rar5_solid.rar";
670
671	/* Skip all */
672
673	PROLOGUE(reffile);
674	assertA(0 == archive_read_next_header(a, &ae));
675	assertEqualString("test.bin", archive_entry_pathname(ae));
676	assertA(0 == archive_read_next_header(a, &ae));
677	assertEqualString("test1.bin", archive_entry_pathname(ae));
678	assertA(0 == archive_read_next_header(a, &ae));
679	assertEqualString("test2.bin", archive_entry_pathname(ae));
680	assertA(0 == archive_read_next_header(a, &ae));
681	assertEqualString("test3.bin", archive_entry_pathname(ae));
682	assertA(0 == archive_read_next_header(a, &ae));
683	assertEqualString("test4.bin", archive_entry_pathname(ae));
684	assertA(0 == archive_read_next_header(a, &ae));
685	assertEqualString("test5.bin", archive_entry_pathname(ae));
686	assertA(0 == archive_read_next_header(a, &ae));
687	assertEqualString("test6.bin", archive_entry_pathname(ae));
688	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
689	EPILOGUE();
690}
691
692DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first)
693{
694	const char* reffile = "test_read_format_rar5_solid.rar";
695
696	/* Extract first, skip rest */
697
698	PROLOGUE(reffile);
699	assertA(0 == archive_read_next_header(a, &ae));
700	assertEqualString("test.bin", archive_entry_pathname(ae));
701	assertA(0 == extract_one(a, ae, 0x7CCA70CD));
702	assertA(0 == archive_read_next_header(a, &ae));
703	assertEqualString("test1.bin", archive_entry_pathname(ae));
704	assertA(0 == archive_read_next_header(a, &ae));
705	assertEqualString("test2.bin", archive_entry_pathname(ae));
706	assertA(0 == archive_read_next_header(a, &ae));
707	assertEqualString("test3.bin", archive_entry_pathname(ae));
708	assertA(0 == archive_read_next_header(a, &ae));
709	assertEqualString("test4.bin", archive_entry_pathname(ae));
710	assertA(0 == archive_read_next_header(a, &ae));
711	assertEqualString("test5.bin", archive_entry_pathname(ae));
712	assertA(0 == archive_read_next_header(a, &ae));
713	assertEqualString("test6.bin", archive_entry_pathname(ae));
714	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
715	EPILOGUE();
716}
717
718DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second)
719{
720	const char* reffile = "test_read_format_rar5_solid.rar";
721
722	/* Skip first, extract second, skip rest */
723
724	PROLOGUE(reffile);
725	assertA(0 == archive_read_next_header(a, &ae));
726	assertEqualString("test.bin", archive_entry_pathname(ae));
727	assertA(0 == archive_read_next_header(a, &ae));
728	assertEqualString("test1.bin", archive_entry_pathname(ae));
729	assertA(0 == extract_one(a, ae, 0x7E13B2C6));
730	assertA(0 == archive_read_next_header(a, &ae));
731	assertEqualString("test2.bin", archive_entry_pathname(ae));
732	assertA(0 == archive_read_next_header(a, &ae));
733	assertEqualString("test3.bin", archive_entry_pathname(ae));
734	assertA(0 == archive_read_next_header(a, &ae));
735	assertEqualString("test4.bin", archive_entry_pathname(ae));
736	assertA(0 == archive_read_next_header(a, &ae));
737	assertEqualString("test5.bin", archive_entry_pathname(ae));
738	assertA(0 == archive_read_next_header(a, &ae));
739	assertEqualString("test6.bin", archive_entry_pathname(ae));
740	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
741	EPILOGUE();
742}
743
744DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_last)
745{
746	const char* reffile = "test_read_format_rar5_solid.rar";
747
748	/* Skip all but last, extract last */
749
750	PROLOGUE(reffile);
751	assertA(0 == archive_read_next_header(a, &ae));
752	assertEqualString("test.bin", archive_entry_pathname(ae));
753	assertA(0 == archive_read_next_header(a, &ae));
754	assertEqualString("test1.bin", archive_entry_pathname(ae));
755	assertA(0 == archive_read_next_header(a, &ae));
756	assertEqualString("test2.bin", archive_entry_pathname(ae));
757	assertA(0 == archive_read_next_header(a, &ae));
758	assertEqualString("test3.bin", archive_entry_pathname(ae));
759	assertA(0 == archive_read_next_header(a, &ae));
760	assertEqualString("test4.bin", archive_entry_pathname(ae));
761	assertA(0 == archive_read_next_header(a, &ae));
762	assertEqualString("test5.bin", archive_entry_pathname(ae));
763	assertA(0 == archive_read_next_header(a, &ae));
764	assertEqualString("test6.bin", archive_entry_pathname(ae));
765	assertA(0 == extract_one(a, ae, 0x36A448FF));
766	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
767	EPILOGUE();
768}
769
770DEFINE_TEST(test_read_format_rar5_extract_win32)
771{
772	PROLOGUE("test_read_format_rar5_win32.rar");
773	assertA(0 == archive_read_next_header(a, &ae));
774	assertEqualString("testdir", archive_entry_pathname(ae));
775	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
776	assertA(0 == extract_one(a, ae, 0));
777	assertA(0 == archive_read_next_header(a, &ae));
778	assertEqualString("test.bin", archive_entry_pathname(ae));
779	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
780	assertA(0 == extract_one(a, ae, 0x7CCA70CD));
781	assertA(0 == archive_read_next_header(a, &ae));
782	assertEqualString("test1.bin", archive_entry_pathname(ae));
783	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
784	assertA(0 == extract_one(a, ae, 0x7E13B2C6));
785	assertA(0 == archive_read_next_header(a, &ae));
786	/* Read only file */
787	assertEqualString("test2.bin", archive_entry_pathname(ae));
788	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444);
789	assertA(0 == extract_one(a, ae, 0xF166AFCB));
790	assertA(0 == archive_read_next_header(a, &ae));
791	assertEqualString("test3.bin", archive_entry_pathname(ae));
792	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
793	assertA(0 == extract_one(a, ae, 0x9FB123D9));
794	assertA(0 == archive_read_next_header(a, &ae));
795	assertEqualString("test4.bin", archive_entry_pathname(ae));
796	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
797	assertA(0 == extract_one(a, ae, 0x10C43ED4));
798	assertA(0 == archive_read_next_header(a, &ae));
799	assertEqualString("test5.bin", archive_entry_pathname(ae));
800	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
801	assertA(0 == extract_one(a, ae, 0xB9D155F2));
802	assertA(0 == archive_read_next_header(a, &ae));
803	assertEqualString("test6.bin", archive_entry_pathname(ae));
804	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
805	assertA(0 == extract_one(a, ae, 0x36A448FF));
806	EPILOGUE();
807}
808
809DEFINE_TEST(test_read_format_rar5_unicode)
810{
811#if !defined(WIN32) || defined(__CYGWIN__)
812	skipping("Skipping test on non-Windows");
813	return;
814#else
815	/* Corresponds to the names:
816	 * ��������.txt
817	 * �������������������������������� ����������������.txt
818	 * ������������ ������������.txt */
819	const wchar_t* emoji_name = L"\U0001f44b\U0001f30e.txt";
820	const wchar_t* italic_name = L"\U0001d4ae\U0001d4ce\U0001d4c2\U0001d4b7\U0001d45c\U0001d4c1\U0001d4be\U0001d4b8 \U0001d43f\U0001d4be\U0001d4c3\U0001d4c0.txt";
821	const wchar_t* circle_name = L"\u24bd\u24d0\u24e1\u24d3 \u24c1\u24d8\u24dd\u24da.txt";
822
823	PROLOGUE("test_read_format_rar5_unicode.rar");
824	assertA(0 == archive_read_next_header(a, &ae));
825	assertEqualWString(emoji_name, archive_entry_pathname_w(ae));
826	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
827	assertA(0 == archive_read_next_header(a, &ae));
828	assertEqualWString(circle_name, archive_entry_pathname_w(ae));
829	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
830	assertEqualWString(emoji_name, archive_entry_hardlink_w(ae));
831	assertA(0 == archive_read_next_header(a, &ae));
832	assertEqualWString(italic_name, archive_entry_pathname_w(ae));
833	assertEqualInt(archive_entry_mode(ae), AE_IFLNK | 0644);
834	assertEqualWString(emoji_name, archive_entry_symlink_w(ae));
835	EPILOGUE();
836#endif
837}
838
839DEFINE_TEST(test_read_format_rar5_block_by_block)
840{
841	/* This test uses strange buffer sizes intentionally. */
842
843	struct archive_entry *ae;
844	struct archive *a;
845	uint8_t buf[173];
846	int bytes_read;
847	uint32_t computed_crc = 0;
848
849	extract_reference_file("test_read_format_rar5_compressed.rar");
850	assert((a = archive_read_new()) != NULL);
851	assertA(0 == archive_read_support_filter_all(a));
852	assertA(0 == archive_read_support_format_all(a));
853	assertA(0 == archive_read_open_filename(a, "test_read_format_rar5_compressed.rar", 130));
854	assertA(0 == archive_read_next_header(a, &ae));
855	assertEqualString("test.bin", archive_entry_pathname(ae));
856	assertEqualInt(1200, archive_entry_size(ae));
857
858	/* File size is 1200 bytes, we're reading it using a buffer of 173 bytes.
859	 * Libarchive is configured to use a buffer of 130 bytes. */
860
861	while(1) {
862		/* archive_read_data should return one of:
863		 * a) 0, if there is no more data to be read,
864		 * b) negative value, if there was an error,
865		 * c) positive value, meaning how many bytes were read.
866		 */
867
868		bytes_read = archive_read_data(a, buf, sizeof(buf));
869		assertA(bytes_read >= 0);
870		if(bytes_read <= 0)
871			break;
872
873		computed_crc = crc32(computed_crc, buf, bytes_read);
874	}
875
876	assertEqualInt(computed_crc, 0x7CCA70CD);
877	EPILOGUE();
878}
879
880DEFINE_TEST(test_read_format_rar5_owner)
881{
882	const int DATA_SIZE = 5;
883	uint8_t buff[5];
884
885	PROLOGUE("test_read_format_rar5_owner.rar");
886
887	assertA(0 == archive_read_next_header(a, &ae));
888	assertEqualString("root.txt", archive_entry_pathname(ae));
889	assertEqualString("root", archive_entry_uname(ae));
890	assertEqualString("wheel", archive_entry_gname(ae));
891	assertA((int) archive_entry_mtime(ae) > 0);
892	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
893	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
894
895	assertA(0 == archive_read_next_header(a, &ae));
896	assertEqualString("nobody.txt", archive_entry_pathname(ae));
897	assertEqualString("nobody", archive_entry_uname(ae));
898	assertEqualString("nogroup", archive_entry_gname(ae));
899	assertA((int) archive_entry_mtime(ae) > 0);
900	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
901	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
902
903	assertA(0 == archive_read_next_header(a, &ae));
904	assertEqualString("numeric.txt", archive_entry_pathname(ae));
905	assertEqualInt(9999, archive_entry_uid(ae));
906	assertEqualInt(8888, archive_entry_gid(ae));
907	assertA((int) archive_entry_mtime(ae) > 0);
908	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
909	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
910
911	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
912
913	EPILOGUE();
914}
915
916DEFINE_TEST(test_read_format_rar5_symlink)
917{
918	const int DATA_SIZE = 5;
919	uint8_t buff[5];
920
921	PROLOGUE("test_read_format_rar5_symlink.rar");
922
923	assertA(0 == archive_read_next_header(a, &ae));
924	assertEqualString("file.txt", archive_entry_pathname(ae));
925	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
926	assertA((int) archive_entry_mtime(ae) > 0);
927	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
928	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
929
930	assertA(0 == archive_read_next_header(a, &ae));
931	assertEqualString("symlink.txt", archive_entry_pathname(ae));
932	assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
933	assertEqualString("file.txt", archive_entry_symlink(ae));
934	assertEqualInt(AE_SYMLINK_TYPE_FILE, archive_entry_symlink_type(ae));
935	assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
936
937	assertA(0 == archive_read_next_header(a, &ae));
938	assertEqualString("dirlink", archive_entry_pathname(ae));
939	assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
940	assertEqualString("dir", archive_entry_symlink(ae));
941	assertEqualInt(AE_SYMLINK_TYPE_DIRECTORY, archive_entry_symlink_type(ae));
942	assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
943
944	assertA(0 == archive_read_next_header(a, &ae));
945	assertEqualString("dir", archive_entry_pathname(ae));
946	assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
947	assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
948
949	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
950
951	EPILOGUE();
952}
953
954DEFINE_TEST(test_read_format_rar5_hardlink)
955{
956	const int DATA_SIZE = 5;
957	uint8_t buff[5];
958
959	PROLOGUE("test_read_format_rar5_hardlink.rar");
960
961	assertA(0 == archive_read_next_header(a, &ae));
962	assertEqualString("file.txt", archive_entry_pathname(ae));
963	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
964	assertA((int) archive_entry_mtime(ae) > 0);
965	assertEqualInt(DATA_SIZE, archive_entry_size(ae));
966	assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
967
968	assertA(0 == archive_read_next_header(a, &ae));
969	assertEqualString("hardlink.txt", archive_entry_pathname(ae));
970	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
971	assertEqualString("file.txt", archive_entry_hardlink(ae));
972	assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
973
974	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
975
976	EPILOGUE();
977}
978
979DEFINE_TEST(test_read_format_rar5_extra_field_version)
980{
981	PROLOGUE("test_read_format_rar5_extra_field_version.rar");
982
983	assertA(0 == archive_read_next_header(a, &ae));
984	assertEqualString("bin/2to3;1", archive_entry_pathname(ae));
985	assertA(0 == extract_one(a, ae, 0xF24181B7));
986
987	assertA(0 == archive_read_next_header(a, &ae));
988	assertEqualString("bin/2to3", archive_entry_pathname(ae));
989	assertA(0 == extract_one(a, ae, 0xF24181B7));
990
991	assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
992
993	EPILOGUE();
994}
995
996DEFINE_TEST(test_read_format_rar5_readtables_overflow)
997{
998	uint8_t buf[16];
999
1000	PROLOGUE("test_read_format_rar5_readtables_overflow.rar");
1001
1002	/* This archive is invalid. However, processing it shouldn't cause any
1003	 * buffer overflow errors during reading rar5 tables. */
1004
1005	(void) archive_read_next_header(a, &ae);
1006	(void) archive_read_data(a, buf, sizeof(buf));
1007	(void) archive_read_next_header(a, &ae);
1008
1009	EPILOGUE();
1010}
1011
1012DEFINE_TEST(test_read_format_rar5_leftshift1)
1013{
1014	uint8_t buf[16];
1015
1016	PROLOGUE("test_read_format_rar5_leftshift1.rar");
1017
1018	/* This archive is invalid. However, processing it shouldn't cause any
1019	 * errors related to undefined operations when using -fsanitize. */
1020
1021	(void) archive_read_next_header(a, &ae);
1022	(void) archive_read_data(a, buf, sizeof(buf));
1023	(void) archive_read_next_header(a, &ae);
1024
1025	EPILOGUE();
1026}
1027
1028DEFINE_TEST(test_read_format_rar5_leftshift2)
1029{
1030	uint8_t buf[16];
1031
1032	PROLOGUE("test_read_format_rar5_leftshift2.rar");
1033
1034	/* This archive is invalid. However, processing it shouldn't cause any
1035	 * errors related to undefined operations when using -fsanitize. */
1036
1037	(void) archive_read_next_header(a, &ae);
1038	(void) archive_read_data(a, buf, sizeof(buf));
1039	(void) archive_read_next_header(a, &ae);
1040
1041	EPILOGUE();
1042}
1043
1044DEFINE_TEST(test_read_format_rar5_truncated_huff)
1045{
1046	uint8_t buf[16];
1047
1048	PROLOGUE("test_read_format_rar5_truncated_huff.rar");
1049
1050	/* This archive is invalid. However, processing it shouldn't cause any
1051	 * errors related to undefined operations when using -fsanitize. */
1052
1053	(void) archive_read_next_header(a, &ae);
1054	(void) archive_read_data(a, buf, sizeof(buf));
1055	(void) archive_read_next_header(a, &ae);
1056
1057	EPILOGUE();
1058}
1059
1060DEFINE_TEST(test_read_format_rar5_invalid_dict_reference)
1061{
1062	uint8_t buf[16];
1063
1064	PROLOGUE("test_read_format_rar5_invalid_dict_reference.rar");
1065
1066	/* This test should fail on parsing the header. */
1067	assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK);
1068
1069	/* This archive is invalid. However, processing it shouldn't cause any
1070	 * errors related to buffer underflow when using -fsanitize. */
1071	assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
1072
1073	/* This test only cares about not returning success here. */
1074	assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
1075
1076	EPILOGUE();
1077}
1078
1079DEFINE_TEST(test_read_format_rar5_distance_overflow)
1080{
1081	uint8_t buf[16];
1082
1083	PROLOGUE("test_read_format_rar5_distance_overflow.rar");
1084
1085	/* This archive is invalid. However, processing it shouldn't cause any
1086	 * errors related to variable overflows when using -fsanitize. */
1087
1088	(void) archive_read_next_header(a, &ae);
1089	(void) archive_read_data(a, buf, sizeof(buf));
1090	(void) archive_read_next_header(a, &ae);
1091
1092	EPILOGUE();
1093}
1094
1095DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream)
1096{
1097	uint8_t buf[16];
1098
1099	PROLOGUE("test_read_format_rar5_nonempty_dir_stream.rar");
1100
1101	/* This archive is invalid. However, processing it shouldn't cause any
1102	 * errors related to buffer overflows when using -fsanitize. */
1103
1104	(void) archive_read_next_header(a, &ae);
1105	(void) archive_read_data(a, buf, sizeof(buf));
1106	(void) archive_read_next_header(a, &ae);
1107
1108	EPILOGUE();
1109}
1110
1111DEFINE_TEST(test_read_format_rar5_fileattr)
1112{
1113	unsigned long set, clear, flag;
1114
1115	flag = 0;
1116
1117	PROLOGUE("test_read_format_rar5_fileattr.rar");
1118
1119	assertA(0 == archive_read_next_header(a, &ae));
1120	assertEqualInt(archive_entry_mode(ae), 0444 | AE_IFREG);
1121	assertEqualString("readonly.txt", archive_entry_pathname(ae));
1122	assertEqualString("rdonly", archive_entry_fflags_text(ae));
1123	archive_entry_fflags(ae, &set, &clear);
1124#if defined(__FreeBSD__)
1125	flag = UF_READONLY;
1126#elif defined(_WIN32) && !defined(CYGWIN)
1127	flag = FILE_ATTRIBUTE_READONLY;
1128#endif
1129	assertEqualInt(flag, set & flag);
1130
1131	assertA(0 == archive_read_next_header(a, &ae));
1132	assertEqualInt(archive_entry_mode(ae), 0644 | AE_IFREG);
1133	assertEqualString("hidden.txt", archive_entry_pathname(ae));
1134	assertEqualString("hidden", archive_entry_fflags_text(ae));
1135	archive_entry_fflags(ae, &set, &clear);
1136#if defined(__FreeBSD__)
1137	flag = UF_HIDDEN;
1138#elif defined(_WIN32) && !defined(CYGWIN)
1139	flag = FILE_ATTRIBUTE_HIDDEN;
1140#endif
1141	assertEqualInt(flag, set & flag);
1142
1143	assertA(0 == archive_read_next_header(a, &ae));
1144	assertEqualInt(archive_entry_mode(ae), 0644 | AE_IFREG);
1145	assertEqualString("system.txt", archive_entry_pathname(ae));
1146	assertEqualString("system", archive_entry_fflags_text(ae));
1147	archive_entry_fflags(ae, &set, &clear);
1148#if defined(__FreeBSD__)
1149	flag = UF_SYSTEM;;
1150#elif defined(_WIN32) && !defined(CYGWIN)
1151	flag = FILE_ATTRIBUTE_SYSTEM;
1152#endif
1153	assertEqualInt(flag, set & flag);
1154
1155	assertA(0 == archive_read_next_header(a, &ae));
1156	assertEqualInt(archive_entry_mode(ae), 0444 | AE_IFREG);
1157	assertEqualString("ro_hidden.txt", archive_entry_pathname(ae));
1158	assertEqualString("rdonly,hidden", archive_entry_fflags_text(ae));
1159	archive_entry_fflags(ae, &set, &clear);
1160#if defined(__FreeBSD__)
1161	flag = UF_READONLY | UF_HIDDEN;
1162#elif defined(_WIN32) && !defined(CYGWIN)
1163	flag = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN;
1164#endif
1165	assertEqualInt(flag, set & flag);
1166
1167	assertA(0 == archive_read_next_header(a, &ae));
1168	assertEqualInt(archive_entry_mode(ae), 0555 | AE_IFDIR);
1169	assertEqualString("dir_readonly", archive_entry_pathname(ae));
1170	assertEqualString("rdonly", archive_entry_fflags_text(ae));
1171	archive_entry_fflags(ae, &set, &clear);
1172#if defined(__FreeBSD__)
1173	flag = UF_READONLY;
1174#elif defined(_WIN32) && !defined(CYGWIN)
1175	flag = FILE_ATTRIBUTE_READONLY;
1176#endif
1177	assertEqualInt(flag, set & flag);
1178
1179	assertA(0 == archive_read_next_header(a, &ae));
1180	assertEqualInt(archive_entry_mode(ae), 0755 | AE_IFDIR);
1181	assertEqualString("dir_hidden", archive_entry_pathname(ae));
1182	assertEqualString("hidden", archive_entry_fflags_text(ae));
1183	archive_entry_fflags(ae, &set, &clear);
1184#if defined(__FreeBSD__)
1185	flag = UF_HIDDEN;
1186#elif defined(_WIN32) && !defined(CYGWIN)
1187	flag = FILE_ATTRIBUTE_HIDDEN;
1188#endif
1189	assertEqualInt(flag, set & flag);
1190
1191	assertA(0 == archive_read_next_header(a, &ae));
1192	assertEqualInt(archive_entry_mode(ae), 0755 | AE_IFDIR);
1193	assertEqualString("dir_system", archive_entry_pathname(ae));
1194	assertEqualString("system", archive_entry_fflags_text(ae));
1195	archive_entry_fflags(ae, &set, &clear);
1196#if defined(__FreeBSD__)
1197	flag = UF_SYSTEM;
1198#elif defined(_WIN32) && !defined(CYGWIN)
1199	flag = FILE_ATTRIBUTE_SYSTEM;
1200#endif
1201	assertEqualInt(flag, set & flag);
1202
1203	assertA(0 == archive_read_next_header(a, &ae));
1204	assertEqualInt(archive_entry_mode(ae), 0555 | AE_IFDIR);
1205	assertEqualString("dir_rohidden", archive_entry_pathname(ae));
1206	assertEqualString("rdonly,hidden", archive_entry_fflags_text(ae));
1207	archive_entry_fflags(ae, &set, &clear);
1208#if defined(__FreeBSD__)
1209	flag = UF_READONLY | UF_HIDDEN;
1210#elif defined(_WIN32) && !defined(CYGWIN)
1211	flag = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN;
1212#endif
1213	assertEqualInt(flag, set & flag);
1214
1215	EPILOGUE();
1216}
1217
1218DEFINE_TEST(test_read_format_rar5_different_window_size)
1219{
1220	char buf[4096];
1221	PROLOGUE("test_read_format_rar5_different_window_size.rar");
1222
1223	/* Return codes of those calls are ignored, because this sample file
1224	 * is invalid. However, the unpacker shouldn't produce any SIGSEGV
1225	 * errors during processing. */
1226
1227	(void) archive_read_next_header(a, &ae);
1228	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1229
1230	(void) archive_read_next_header(a, &ae);
1231	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1232
1233	(void) archive_read_next_header(a, &ae);
1234	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1235
1236	EPILOGUE();
1237}
1238
1239DEFINE_TEST(test_read_format_rar5_window_buf_and_size_desync)
1240{
1241	/* oss fuzz 30442 */
1242
1243	char buf[4096];
1244	PROLOGUE("test_read_format_rar5_window_buf_and_size_desync.rar");
1245
1246	/* Return codes of those calls are ignored, because this sample file
1247	 * is invalid. However, the unpacker shouldn't produce any SIGSEGV
1248	 * errors during processing. */
1249
1250	(void) archive_read_next_header(a, &ae);
1251	while(0 < archive_read_data(a, buf, 46)) {}
1252
1253	EPILOGUE();
1254}
1255
1256DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary)
1257{
1258	char buf[4096];
1259	PROLOGUE("test_read_format_rar5_arm_filter_on_window_boundary.rar");
1260
1261	/* Return codes of those calls are ignored, because this sample file
1262	 * is invalid. However, the unpacker shouldn't produce any SIGSEGV
1263	 * errors during processing. */
1264
1265	(void) archive_read_next_header(a, &ae);
1266	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1267
1268	EPILOGUE();
1269}
1270
1271DEFINE_TEST(test_read_format_rar5_different_solid_window_size)
1272{
1273	char buf[4096];
1274	PROLOGUE("test_read_format_rar5_different_solid_window_size.rar");
1275
1276	/* Return codes of those calls are ignored, because this sample file
1277	 * is invalid. However, the unpacker shouldn't produce any SIGSEGV
1278	 * errors during processing. */
1279
1280	(void) archive_read_next_header(a, &ae);
1281	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1282
1283	(void) archive_read_next_header(a, &ae);
1284	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1285
1286	(void) archive_read_next_header(a, &ae);
1287	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1288
1289	EPILOGUE();
1290}
1291
1292DEFINE_TEST(test_read_format_rar5_different_winsize_on_merge)
1293{
1294	char buf[4096];
1295	PROLOGUE("test_read_format_rar5_different_winsize_on_merge.rar");
1296
1297	/* Return codes of those calls are ignored, because this sample file
1298	 * is invalid. However, the unpacker shouldn't produce any SIGSEGV
1299	 * errors during processing. */
1300
1301	(void) archive_read_next_header(a, &ae);
1302	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1303
1304	EPILOGUE();
1305}
1306
1307DEFINE_TEST(test_read_format_rar5_block_size_is_too_small)
1308{
1309	char buf[4096];
1310	PROLOGUE("test_read_format_rar5_block_size_is_too_small.rar");
1311
1312	/* This file is damaged, so those functions should return failure.
1313	 * Additionally, SIGSEGV shouldn't be raised during execution
1314	 * of those functions. */
1315
1316	assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK);
1317	assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
1318
1319	EPILOGUE();
1320}
1321
1322DEFINE_TEST(test_read_format_rar5_sfx)
1323{
1324	struct archive *a;
1325	struct archive_entry *ae;
1326	int bs = 10240;
1327	char buff[32];
1328	const char reffile[] = "test_read_format_rar5_sfx.exe";
1329	const char test_txt[] = "123";
1330	int size = sizeof(test_txt) - 1;
1331
1332	extract_reference_file(reffile);
1333	assert((a = archive_read_new()) != NULL);
1334	assertA(0 == archive_read_support_filter_all(a));
1335	assertA(0 == archive_read_support_format_all(a));
1336	assertA(0 == archive_read_open_filename(a, reffile, bs));
1337
1338	assertA(0 == archive_read_next_header(a, &ae));
1339	assertEqualString("test.txt.txt", archive_entry_pathname(ae));
1340
1341	assertA(size == archive_read_data(a, buff, size));
1342	assertEqualMem(buff, test_txt, size);
1343
1344	EPILOGUE();
1345}
1346
1347DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read)
1348{
1349	/* oss fuzz 30448 */
1350
1351	char buf[4096];
1352	PROLOGUE("test_read_format_rar5_decode_number_out_of_bounds_read.rar");
1353
1354	/* Return codes of those calls are ignored, because this sample file
1355	 * is invalid. However, the unpacker shouldn't produce any SIGSEGV
1356	 * errors during processing. */
1357
1358	(void) archive_read_next_header(a, &ae);
1359	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1360
1361	EPILOGUE();
1362}
1363
1364DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file)
1365{
1366	/* oss fuzz 30459 */
1367
1368	char buf[4096];
1369	PROLOGUE("test_read_format_rar5_bad_window_sz_in_mltarc_file.rar");
1370
1371	/* This file is damaged, so those functions should return failure.
1372	 * Additionally, SIGSEGV shouldn't be raised during execution
1373	 * of those functions. */
1374
1375	(void) archive_read_next_header(a, &ae);
1376	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1377	(void) archive_read_next_header(a, &ae);
1378	while(0 < archive_read_data(a, buf, sizeof(buf))) {}
1379
1380	EPILOGUE();
1381}
1382
1383DEFINE_TEST(test_read_format_rar5_read_data_block_uninitialized_offset)
1384{
1385	const void *buf;
1386	size_t size;
1387	la_int64_t offset;
1388
1389	PROLOGUE("test_read_format_rar5_compressed.rar");
1390	assertA(0 == archive_read_next_header(a, &ae));
1391
1392	/* A real code may pass a pointer to an uninitialized variable as an offset
1393	 * output argument. Here we want to check this situation. But because
1394	 * relying on a value of an uninitialized variable in a test is not a good
1395	 * idea, let's pretend that 0xdeadbeef is a random value of the
1396	 * uninitialized variable. */
1397	offset = 0xdeadbeef;
1398	assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &buf, &size, &offset));
1399	/* The test archive doesn't contain a sparse file. And because of that, here
1400	 * we assume that the first returned offset should be 0. */
1401	assertEqualInt(0, offset);
1402
1403	EPILOGUE();
1404}
1405