test_read_format_rar5.c revision 342360
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 = 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_stored)
120{
121    const char helloworld_txt[] = "hello libarchive test suite!\n";
122    la_ssize_t file_size = sizeof(helloworld_txt) - 1;
123    char buff[64];
124
125    PROLOGUE("test_read_format_rar5_stored.rar");
126
127    assertA(0 == archive_read_next_header(a, &ae));
128    assertEqualString("helloworld.txt", archive_entry_pathname(ae));
129    assertA((int) archive_entry_mtime(ae) > 0);
130    assertA((int) archive_entry_ctime(ae) == 0);
131    assertA((int) archive_entry_atime(ae) == 0);
132    assertEqualInt(file_size, archive_entry_size(ae));
133    assertEqualInt(33188, archive_entry_mode(ae));
134    assertA(file_size == archive_read_data(a, buff, file_size));
135    assertEqualMem(buff, helloworld_txt, file_size);
136    assertEqualInt(archive_entry_is_encrypted(ae), 0);
137
138    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
139
140    EPILOGUE();
141}
142
143DEFINE_TEST(test_read_format_rar5_compressed)
144{
145    const int DATA_SIZE = 1200;
146    uint8_t buff[DATA_SIZE];
147
148    PROLOGUE("test_read_format_rar5_compressed.rar");
149
150    assertA(0 == archive_read_next_header(a, &ae));
151    assertEqualString("test.bin", archive_entry_pathname(ae));
152    assertA((int) archive_entry_mtime(ae) > 0);
153    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
154    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
155    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
156    verify_data(buff, 0, DATA_SIZE);
157
158    EPILOGUE();
159}
160
161DEFINE_TEST(test_read_format_rar5_multiple_files)
162{
163    const int DATA_SIZE = 4096;
164    uint8_t buff[DATA_SIZE];
165
166    PROLOGUE("test_read_format_rar5_multiple_files.rar");
167
168    /* There should be 4 files inside this test file. Check for their
169     * existence, and also check the contents of those test files. */
170
171    assertA(0 == archive_read_next_header(a, &ae));
172    assertEqualString("test1.bin", archive_entry_pathname(ae));
173    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
174    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
175    assertA(verify_data(buff, 1, DATA_SIZE));
176
177    assertA(0 == archive_read_next_header(a, &ae));
178    assertEqualString("test2.bin", archive_entry_pathname(ae));
179    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
180    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
181    assertA(verify_data(buff, 2, DATA_SIZE));
182
183    assertA(0 == archive_read_next_header(a, &ae));
184    assertEqualString("test3.bin", archive_entry_pathname(ae));
185    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
186    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
187    assertA(verify_data(buff, 3, DATA_SIZE));
188
189    assertA(0 == archive_read_next_header(a, &ae));
190    assertEqualString("test4.bin", archive_entry_pathname(ae));
191    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
192    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
193    assertA(verify_data(buff, 4, DATA_SIZE));
194
195    /* There should be no more files in this archive. */
196
197    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
198    EPILOGUE();
199}
200
201/* This test is really the same as the test above, but it deals with a solid
202 * archive instead of a regular archive. The test solid archive contains the
203 * same set of files as regular test archive, but it's size is 2x smaller,
204 * because solid archives reuse the window buffer from previous compressed
205 * files, so it's able to compress lots of small files more effectively. */
206
207DEFINE_TEST(test_read_format_rar5_multiple_files_solid)
208{
209    const int DATA_SIZE = 4096;
210    uint8_t buff[DATA_SIZE];
211
212    PROLOGUE("test_read_format_rar5_multiple_files_solid.rar");
213
214    assertA(0 == archive_read_next_header(a, &ae));
215    assertEqualString("test1.bin", archive_entry_pathname(ae));
216    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
217    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
218    assertA(verify_data(buff, 1, DATA_SIZE));
219
220    assertA(0 == archive_read_next_header(a, &ae));
221    assertEqualString("test2.bin", archive_entry_pathname(ae));
222    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
223    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
224    assertA(verify_data(buff, 2, DATA_SIZE));
225
226    assertA(0 == archive_read_next_header(a, &ae));
227    assertEqualString("test3.bin", archive_entry_pathname(ae));
228    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
229    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
230    assertA(verify_data(buff, 3, DATA_SIZE));
231
232    assertA(0 == archive_read_next_header(a, &ae));
233    assertEqualString("test4.bin", archive_entry_pathname(ae));
234    assertEqualInt(DATA_SIZE, archive_entry_size(ae));
235    assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
236    assertA(verify_data(buff, 4, DATA_SIZE));
237
238    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
239    EPILOGUE();
240}
241
242DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all)
243{
244    const char* reffiles[] = {
245        "test_read_format_rar5_multiarchive.part01.rar",
246        "test_read_format_rar5_multiarchive.part02.rar",
247        "test_read_format_rar5_multiarchive.part03.rar",
248        "test_read_format_rar5_multiarchive.part04.rar",
249        "test_read_format_rar5_multiarchive.part05.rar",
250        "test_read_format_rar5_multiarchive.part06.rar",
251        "test_read_format_rar5_multiarchive.part07.rar",
252        "test_read_format_rar5_multiarchive.part08.rar",
253        NULL
254    };
255
256    PROLOGUE_MULTI(reffiles);
257    assertA(0 == archive_read_next_header(a, &ae));
258    assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdcat_test", archive_entry_pathname(ae));
259    assertA(0 == archive_read_next_header(a, &ae));
260    assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdtar_test", archive_entry_pathname(ae));
261    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
262    EPILOGUE();
263}
264
265DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_first)
266{
267    const char* reffiles[] = {
268        "test_read_format_rar5_multiarchive.part01.rar",
269        "test_read_format_rar5_multiarchive.part02.rar",
270        "test_read_format_rar5_multiarchive.part03.rar",
271        "test_read_format_rar5_multiarchive.part04.rar",
272        "test_read_format_rar5_multiarchive.part05.rar",
273        "test_read_format_rar5_multiarchive.part06.rar",
274        "test_read_format_rar5_multiarchive.part07.rar",
275        "test_read_format_rar5_multiarchive.part08.rar",
276        NULL
277    };
278
279    PROLOGUE_MULTI(reffiles);
280    assertA(0 == archive_read_next_header(a, &ae));
281    assertA(0 == extract_one(a, ae, 0x35277473));
282    assertA(0 == archive_read_next_header(a, &ae));
283    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
284    EPILOGUE();
285}
286
287DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second)
288{
289    const char* reffiles[] = {
290        "test_read_format_rar5_multiarchive.part01.rar",
291        "test_read_format_rar5_multiarchive.part02.rar",
292        "test_read_format_rar5_multiarchive.part03.rar",
293        "test_read_format_rar5_multiarchive.part04.rar",
294        "test_read_format_rar5_multiarchive.part05.rar",
295        "test_read_format_rar5_multiarchive.part06.rar",
296        "test_read_format_rar5_multiarchive.part07.rar",
297        "test_read_format_rar5_multiarchive.part08.rar",
298        NULL
299    };
300
301    PROLOGUE_MULTI(reffiles);
302    assertA(0 == archive_read_next_header(a, &ae));
303    assertA(0 == archive_read_next_header(a, &ae));
304    assertA(0 == extract_one(a, ae, 0xE59665F8));
305    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
306    EPILOGUE();
307}
308
309DEFINE_TEST(test_read_format_rar5_blake2)
310{
311    const la_ssize_t proper_size = 814;
312    uint8_t buf[proper_size];
313
314    PROLOGUE("test_read_format_rar5_blake2.rar");
315    assertA(0 == archive_read_next_header(a, &ae));
316    assertEqualInt(proper_size, archive_entry_size(ae));
317
318    /* Should blake2 calculation fail, we'll get a failure return
319     * value from archive_read_data(). */
320
321    assertA(proper_size == archive_read_data(a, buf, proper_size));
322
323    /* To be extra pedantic, let's also check crc32 of the poem. */
324    assertEqualInt(crc32(0, buf, proper_size), 0x7E5EC49E);
325
326    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
327    EPILOGUE();
328}
329
330DEFINE_TEST(test_read_format_rar5_arm_filter)
331{
332    /* This test unpacks a file that uses an ARM filter. The DELTA
333     * and X86 filters are tested implicitly in the "multiarchive_skip"
334     * test. */
335
336    const la_ssize_t proper_size = 90808;
337    uint8_t buf[proper_size];
338
339    PROLOGUE("test_read_format_rar5_arm.rar");
340    assertA(0 == archive_read_next_header(a, &ae));
341    assertEqualInt(proper_size, archive_entry_size(ae));
342    assertA(proper_size == archive_read_data(a, buf, proper_size));
343
344    /* Yes, RARv5 unpacker itself should calculate the CRC, but in case
345     * the DONT_FAIL_ON_CRC_ERROR define option is enabled during compilation,
346     * let's still fail the test if the unpacked data is wrong. */
347    assertEqualInt(crc32(0, buf, proper_size), 0x886F91EB);
348
349    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
350    EPILOGUE();
351}
352
353DEFINE_TEST(test_read_format_rar5_stored_skip_all)
354{
355    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
356
357    PROLOGUE(fname);
358    assertA(0 == archive_read_next_header(a, &ae));
359    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
360    assertA(0 == archive_read_next_header(a, &ae));
361    assertEqualString("cebula.txt", archive_entry_pathname(ae));
362    assertA(0 == archive_read_next_header(a, &ae));
363    assertEqualString("test.bin", archive_entry_pathname(ae));
364    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
365    EPILOGUE();
366}
367
368DEFINE_TEST(test_read_format_rar5_stored_skip_in_part)
369{
370    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
371    char buf[6];
372
373    /* Skip first, extract in part rest. */
374
375    PROLOGUE(fname);
376    assertA(0 == archive_read_next_header(a, &ae));
377    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
378    assertA(0 == archive_read_next_header(a, &ae));
379    assertEqualString("cebula.txt", archive_entry_pathname(ae));
380    assertA(6 == archive_read_data(a, buf, 6));
381    assertEqualInt(0, memcmp(buf, "Cebula", 6));
382    assertA(0 == archive_read_next_header(a, &ae));
383    assertEqualString("test.bin", archive_entry_pathname(ae));
384    assertA(4 == archive_read_data(a, buf, 4));
385    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
386    EPILOGUE();
387}
388
389DEFINE_TEST(test_read_format_rar5_stored_skip_all_but_first)
390{
391    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
392    char buf[405];
393
394    /* Extract first, skip rest. */
395
396    PROLOGUE(fname);
397    assertA(0 == archive_read_next_header(a, &ae));
398    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
399    assertA(405 == archive_read_data(a, buf, sizeof(buf)));
400    assertA(0 == archive_read_next_header(a, &ae));
401    assertEqualString("cebula.txt", archive_entry_pathname(ae));
402    assertA(0 == archive_read_next_header(a, &ae));
403    assertEqualString("test.bin", archive_entry_pathname(ae));
404    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
405    EPILOGUE();
406}
407
408DEFINE_TEST(test_read_format_rar5_stored_skip_all_in_part)
409{
410    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
411    char buf[4];
412
413    /* Extract in part all */
414
415    PROLOGUE(fname);
416    assertA(0 == archive_read_next_header(a, &ae));
417    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
418    assertA(4 == archive_read_data(a, buf, 4));
419    assertA(0 == archive_read_next_header(a, &ae));
420    assertEqualString("cebula.txt", archive_entry_pathname(ae));
421    assertA(4 == archive_read_data(a, buf, 4));
422    assertA(0 == archive_read_next_header(a, &ae));
423    assertEqualString("test.bin", archive_entry_pathname(ae));
424    assertA(4 == archive_read_data(a, buf, 4));
425    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
426    EPILOGUE();
427}
428
429DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all)
430{
431    const char* reffiles[] = {
432        "test_read_format_rar5_multiarchive_solid.part01.rar",
433        "test_read_format_rar5_multiarchive_solid.part02.rar",
434        "test_read_format_rar5_multiarchive_solid.part03.rar",
435        "test_read_format_rar5_multiarchive_solid.part04.rar",
436        NULL
437    };
438
439    PROLOGUE_MULTI(reffiles);
440    assertA(0 == archive_read_next_header(a, &ae));
441    assertEqualString("cebula.txt", archive_entry_pathname(ae));
442    assertA(0 == archive_read_next_header(a, &ae));
443    assertEqualString("test.bin", archive_entry_pathname(ae));
444    assertA(0 == archive_read_next_header(a, &ae));
445    assertEqualString("test1.bin", archive_entry_pathname(ae));
446    assertA(0 == archive_read_next_header(a, &ae));
447    assertEqualString("test2.bin", archive_entry_pathname(ae));
448    assertA(0 == archive_read_next_header(a, &ae));
449    assertEqualString("test3.bin", archive_entry_pathname(ae));
450    assertA(0 == archive_read_next_header(a, &ae));
451    assertEqualString("test4.bin", archive_entry_pathname(ae));
452    assertA(0 == archive_read_next_header(a, &ae));
453    assertEqualString("test5.bin", archive_entry_pathname(ae));
454    assertA(0 == archive_read_next_header(a, &ae));
455    assertEqualString("test6.bin", archive_entry_pathname(ae));
456    assertA(0 == archive_read_next_header(a, &ae));
457    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
458    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
459    EPILOGUE();
460}
461
462DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_first)
463{
464    const char* reffiles[] = {
465        "test_read_format_rar5_multiarchive_solid.part01.rar",
466        "test_read_format_rar5_multiarchive_solid.part02.rar",
467        "test_read_format_rar5_multiarchive_solid.part03.rar",
468        "test_read_format_rar5_multiarchive_solid.part04.rar",
469        NULL
470    };
471
472    PROLOGUE_MULTI(reffiles);
473    assertA(0 == archive_read_next_header(a, &ae));
474    assertEqualString("cebula.txt", archive_entry_pathname(ae));
475    assertA(0 == extract_one(a, ae, 0x7E5EC49E));
476    assertA(0 == archive_read_next_header(a, &ae));
477    assertEqualString("test.bin", archive_entry_pathname(ae));
478    assertA(0 == archive_read_next_header(a, &ae));
479    assertEqualString("test1.bin", archive_entry_pathname(ae));
480    assertA(0 == archive_read_next_header(a, &ae));
481    assertEqualString("test2.bin", archive_entry_pathname(ae));
482    assertA(0 == archive_read_next_header(a, &ae));
483    assertEqualString("test3.bin", archive_entry_pathname(ae));
484    assertA(0 == archive_read_next_header(a, &ae));
485    assertEqualString("test4.bin", archive_entry_pathname(ae));
486    assertA(0 == archive_read_next_header(a, &ae));
487    assertEqualString("test5.bin", archive_entry_pathname(ae));
488    assertA(0 == archive_read_next_header(a, &ae));
489    assertEqualString("test6.bin", archive_entry_pathname(ae));
490    assertA(0 == archive_read_next_header(a, &ae));
491    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
492    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
493    EPILOGUE();
494}
495
496/* "skip_all_but_scnd" -> am I hitting the test name limit here after
497 * expansion of "scnd" to "second"? */
498
499DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_scnd)
500{
501    const char* reffiles[] = {
502        "test_read_format_rar5_multiarchive_solid.part01.rar",
503        "test_read_format_rar5_multiarchive_solid.part02.rar",
504        "test_read_format_rar5_multiarchive_solid.part03.rar",
505        "test_read_format_rar5_multiarchive_solid.part04.rar",
506        NULL
507    };
508
509    PROLOGUE_MULTI(reffiles);
510    assertA(0 == archive_read_next_header(a, &ae));
511    assertEqualString("cebula.txt", archive_entry_pathname(ae));
512    assertA(0 == archive_read_next_header(a, &ae));
513    assertEqualString("test.bin", archive_entry_pathname(ae));
514    assertA(0 == extract_one(a, ae, 0x7CCA70CD));
515    assertA(0 == archive_read_next_header(a, &ae));
516    assertEqualString("test1.bin", archive_entry_pathname(ae));
517    assertA(0 == archive_read_next_header(a, &ae));
518    assertEqualString("test2.bin", archive_entry_pathname(ae));
519    assertA(0 == archive_read_next_header(a, &ae));
520    assertEqualString("test3.bin", archive_entry_pathname(ae));
521    assertA(0 == archive_read_next_header(a, &ae));
522    assertEqualString("test4.bin", archive_entry_pathname(ae));
523    assertA(0 == archive_read_next_header(a, &ae));
524    assertEqualString("test5.bin", archive_entry_pathname(ae));
525    assertA(0 == archive_read_next_header(a, &ae));
526    assertEqualString("test6.bin", archive_entry_pathname(ae));
527    assertA(0 == archive_read_next_header(a, &ae));
528    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
529    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
530    EPILOGUE();
531}
532
533DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_third)
534{
535    const char* reffiles[] = {
536        "test_read_format_rar5_multiarchive_solid.part01.rar",
537        "test_read_format_rar5_multiarchive_solid.part02.rar",
538        "test_read_format_rar5_multiarchive_solid.part03.rar",
539        "test_read_format_rar5_multiarchive_solid.part04.rar",
540        NULL
541    };
542
543    PROLOGUE_MULTI(reffiles);
544    assertA(0 == archive_read_next_header(a, &ae));
545    assertEqualString("cebula.txt", archive_entry_pathname(ae));
546    assertA(0 == archive_read_next_header(a, &ae));
547    assertEqualString("test.bin", archive_entry_pathname(ae));
548    assertA(0 == archive_read_next_header(a, &ae));
549    assertEqualString("test1.bin", archive_entry_pathname(ae));
550    assertA(0 == extract_one(a, ae, 0x7E13B2C6));
551    assertA(0 == archive_read_next_header(a, &ae));
552    assertEqualString("test2.bin", archive_entry_pathname(ae));
553    assertA(0 == archive_read_next_header(a, &ae));
554    assertEqualString("test3.bin", archive_entry_pathname(ae));
555    assertA(0 == archive_read_next_header(a, &ae));
556    assertEqualString("test4.bin", archive_entry_pathname(ae));
557    assertA(0 == archive_read_next_header(a, &ae));
558    assertEqualString("test5.bin", archive_entry_pathname(ae));
559    assertA(0 == archive_read_next_header(a, &ae));
560    assertEqualString("test6.bin", archive_entry_pathname(ae));
561    assertA(0 == archive_read_next_header(a, &ae));
562    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
563    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
564    EPILOGUE();
565}
566
567DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last)
568{
569    const char* reffiles[] = {
570        "test_read_format_rar5_multiarchive_solid.part01.rar",
571        "test_read_format_rar5_multiarchive_solid.part02.rar",
572        "test_read_format_rar5_multiarchive_solid.part03.rar",
573        "test_read_format_rar5_multiarchive_solid.part04.rar",
574        NULL
575    };
576
577    PROLOGUE_MULTI(reffiles);
578    assertA(0 == archive_read_next_header(a, &ae));
579    assertEqualString("cebula.txt", archive_entry_pathname(ae));
580    assertA(0 == archive_read_next_header(a, &ae));
581    assertEqualString("test.bin", archive_entry_pathname(ae));
582    assertA(0 == archive_read_next_header(a, &ae));
583    assertEqualString("test1.bin", archive_entry_pathname(ae));
584    assertA(0 == archive_read_next_header(a, &ae));
585    assertEqualString("test2.bin", archive_entry_pathname(ae));
586    assertA(0 == archive_read_next_header(a, &ae));
587    assertEqualString("test3.bin", archive_entry_pathname(ae));
588    assertA(0 == archive_read_next_header(a, &ae));
589    assertEqualString("test4.bin", archive_entry_pathname(ae));
590    assertA(0 == archive_read_next_header(a, &ae));
591    assertEqualString("test5.bin", archive_entry_pathname(ae));
592    assertA(0 == archive_read_next_header(a, &ae));
593    assertEqualString("test6.bin", archive_entry_pathname(ae));
594    assertA(0 == archive_read_next_header(a, &ae));
595    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
596    assertA(0 == extract_one(a, ae, 0x886F91EB));
597    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
598    EPILOGUE();
599}
600
601DEFINE_TEST(test_read_format_rar5_solid_skip_all)
602{
603    const char* reffile = "test_read_format_rar5_solid.rar";
604
605    /* Skip all */
606
607    PROLOGUE(reffile);
608    assertA(0 == archive_read_next_header(a, &ae));
609    assertEqualString("test.bin", archive_entry_pathname(ae));
610    assertA(0 == archive_read_next_header(a, &ae));
611    assertEqualString("test1.bin", archive_entry_pathname(ae));
612    assertA(0 == archive_read_next_header(a, &ae));
613    assertEqualString("test2.bin", archive_entry_pathname(ae));
614    assertA(0 == archive_read_next_header(a, &ae));
615    assertEqualString("test3.bin", archive_entry_pathname(ae));
616    assertA(0 == archive_read_next_header(a, &ae));
617    assertEqualString("test4.bin", archive_entry_pathname(ae));
618    assertA(0 == archive_read_next_header(a, &ae));
619    assertEqualString("test5.bin", archive_entry_pathname(ae));
620    assertA(0 == archive_read_next_header(a, &ae));
621    assertEqualString("test6.bin", archive_entry_pathname(ae));
622    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
623    EPILOGUE();
624}
625
626DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first)
627{
628    const char* reffile = "test_read_format_rar5_solid.rar";
629
630    /* Extract first, skip rest */
631
632    PROLOGUE(reffile);
633    assertA(0 == archive_read_next_header(a, &ae));
634    assertEqualString("test.bin", archive_entry_pathname(ae));
635    assertA(0 == extract_one(a, ae, 0x7CCA70CD));
636    assertA(0 == archive_read_next_header(a, &ae));
637    assertEqualString("test1.bin", archive_entry_pathname(ae));
638    assertA(0 == archive_read_next_header(a, &ae));
639    assertEqualString("test2.bin", archive_entry_pathname(ae));
640    assertA(0 == archive_read_next_header(a, &ae));
641    assertEqualString("test3.bin", archive_entry_pathname(ae));
642    assertA(0 == archive_read_next_header(a, &ae));
643    assertEqualString("test4.bin", archive_entry_pathname(ae));
644    assertA(0 == archive_read_next_header(a, &ae));
645    assertEqualString("test5.bin", archive_entry_pathname(ae));
646    assertA(0 == archive_read_next_header(a, &ae));
647    assertEqualString("test6.bin", archive_entry_pathname(ae));
648    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
649    EPILOGUE();
650}
651
652DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second)
653{
654    const char* reffile = "test_read_format_rar5_solid.rar";
655
656    /* Skip first, extract second, skip rest */
657
658    PROLOGUE(reffile);
659    assertA(0 == archive_read_next_header(a, &ae));
660    assertEqualString("test.bin", archive_entry_pathname(ae));
661    assertA(0 == archive_read_next_header(a, &ae));
662    assertEqualString("test1.bin", archive_entry_pathname(ae));
663    assertA(0 == extract_one(a, ae, 0x7E13B2C6));
664    assertA(0 == archive_read_next_header(a, &ae));
665    assertEqualString("test2.bin", archive_entry_pathname(ae));
666    assertA(0 == archive_read_next_header(a, &ae));
667    assertEqualString("test3.bin", archive_entry_pathname(ae));
668    assertA(0 == archive_read_next_header(a, &ae));
669    assertEqualString("test4.bin", archive_entry_pathname(ae));
670    assertA(0 == archive_read_next_header(a, &ae));
671    assertEqualString("test5.bin", archive_entry_pathname(ae));
672    assertA(0 == archive_read_next_header(a, &ae));
673    assertEqualString("test6.bin", archive_entry_pathname(ae));
674    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
675    EPILOGUE();
676}
677
678DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_last)
679{
680    const char* reffile = "test_read_format_rar5_solid.rar";
681
682    /* Skip all but last, extract last */
683
684    PROLOGUE(reffile);
685    assertA(0 == archive_read_next_header(a, &ae));
686    assertEqualString("test.bin", archive_entry_pathname(ae));
687    assertA(0 == archive_read_next_header(a, &ae));
688    assertEqualString("test1.bin", archive_entry_pathname(ae));
689    assertA(0 == archive_read_next_header(a, &ae));
690    assertEqualString("test2.bin", archive_entry_pathname(ae));
691    assertA(0 == archive_read_next_header(a, &ae));
692    assertEqualString("test3.bin", archive_entry_pathname(ae));
693    assertA(0 == archive_read_next_header(a, &ae));
694    assertEqualString("test4.bin", archive_entry_pathname(ae));
695    assertA(0 == archive_read_next_header(a, &ae));
696    assertEqualString("test5.bin", archive_entry_pathname(ae));
697    assertA(0 == archive_read_next_header(a, &ae));
698    assertEqualString("test6.bin", archive_entry_pathname(ae));
699    assertA(0 == extract_one(a, ae, 0x36A448FF));
700    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
701    EPILOGUE();
702}
703
704DEFINE_TEST(test_read_format_rar5_extract_win32)
705{
706    PROLOGUE("test_read_format_rar5_win32.rar");
707    assertA(0 == archive_read_next_header(a, &ae));
708    assertEqualString("test.bin", archive_entry_pathname(ae));
709    assertA(0 == extract_one(a, ae, 0x7CCA70CD));
710    assertA(0 == archive_read_next_header(a, &ae));
711    assertEqualString("test1.bin", archive_entry_pathname(ae));
712    assertA(0 == extract_one(a, ae, 0x7E13B2C6));
713    assertA(0 == archive_read_next_header(a, &ae));
714    assertEqualString("test2.bin", archive_entry_pathname(ae));
715    assertA(0 == extract_one(a, ae, 0xF166AFCB));
716    assertA(0 == archive_read_next_header(a, &ae));
717    assertEqualString("test3.bin", archive_entry_pathname(ae));
718    assertA(0 == extract_one(a, ae, 0x9FB123D9));
719    assertA(0 == archive_read_next_header(a, &ae));
720    assertEqualString("test4.bin", archive_entry_pathname(ae));
721    assertA(0 == extract_one(a, ae, 0x10C43ED4));
722    assertA(0 == archive_read_next_header(a, &ae));
723    assertEqualString("test5.bin", archive_entry_pathname(ae));
724    assertA(0 == extract_one(a, ae, 0xB9D155F2));
725    assertA(0 == archive_read_next_header(a, &ae));
726    assertEqualString("test6.bin", archive_entry_pathname(ae));
727    assertA(0 == extract_one(a, ae, 0x36A448FF));
728    EPILOGUE();
729}
730
731DEFINE_TEST(test_read_format_rar5_block_by_block)
732{
733    /* This test uses strange buffer sizes intentionally. */
734
735    struct archive_entry *ae;
736    struct archive *a;
737    uint8_t buf[173];
738    int bytes_read;
739    uint32_t computed_crc = 0;
740
741    extract_reference_file("test_read_format_rar5_compressed.rar");
742    assert((a = archive_read_new()) != NULL);
743    assertA(0 == archive_read_support_filter_all(a));
744    assertA(0 == archive_read_support_format_all(a));
745    assertA(0 == archive_read_open_filename(a, "test_read_format_rar5_compressed.rar", 130));
746    assertA(0 == archive_read_next_header(a, &ae));
747    assertEqualString("test.bin", archive_entry_pathname(ae));
748    assertEqualInt(1200, archive_entry_size(ae));
749
750    /* File size is 1200 bytes, we're reading it using a buffer of 173 bytes.
751     * Libarchive is configured to use a buffer of 130 bytes. */
752
753    while(1) {
754        /* archive_read_data should return one of:
755         * a) 0, if there is no more data to be read,
756         * b) negative value, if there was an error,
757         * c) positive value, meaning how many bytes were read.
758         */
759
760        bytes_read = archive_read_data(a, buf, sizeof(buf));
761        assertA(bytes_read >= 0);
762        if(bytes_read <= 0)
763            break;
764
765        computed_crc = crc32(computed_crc, buf, bytes_read);
766    }
767
768    assertEqualInt(computed_crc, 0x7CCA70CD);
769    EPILOGUE();
770}
771