]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/libarchive/libarchive/test/test_write_format_cpio.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / libarchive / libarchive / test / test_write_format_cpio.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
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 __FBSDID("$FreeBSD$");
27
28 static void
29 test_format(int (*set_format)(struct archive *))
30 {
31         char filedata[64];
32         struct archive_entry *ae;
33         struct archive *a;
34         char *p;
35         size_t used;
36         size_t buffsize = 1000000;
37         char *buff;
38         int damaged = 0;
39
40         buff = malloc(buffsize);
41
42         /* Create a new archive in memory. */
43         assert((a = archive_write_new()) != NULL);
44         assertA(0 == (*set_format)(a));
45         assertA(0 == archive_write_add_filter_none(a));
46         assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
47
48         /*
49          * Write a file to it.
50          */
51         assert((ae = archive_entry_new()) != NULL);
52         archive_entry_set_mtime(ae, 1, 10);
53         assert(1 == archive_entry_mtime(ae));
54         assert(10 == archive_entry_mtime_nsec(ae));
55         p = strdup("file");
56         archive_entry_copy_pathname(ae, p);
57         strcpy(p, "XXXX");
58         free(p);
59         assertEqualString("file", archive_entry_pathname(ae));
60         archive_entry_set_mode(ae, S_IFREG | 0755);
61         assert((S_IFREG | 0755) == archive_entry_mode(ae));
62         archive_entry_set_size(ae, 8);
63
64         assertA(0 == archive_write_header(a, ae));
65         archive_entry_free(ae);
66         assertA(8 == archive_write_data(a, "12345678", 9));
67
68         /*
69          * Write another file to it.
70          */
71         assert((ae = archive_entry_new()) != NULL);
72         archive_entry_set_mtime(ae, 1, 10);
73         assert(1 == archive_entry_mtime(ae));
74         assert(10 == archive_entry_mtime_nsec(ae));
75         p = strdup("file2");
76         archive_entry_copy_pathname(ae, p);
77         strcpy(p, "XXXX");
78         free(p);
79         assertEqualString("file2", archive_entry_pathname(ae));
80         archive_entry_set_mode(ae, S_IFREG | 0755);
81         assert((S_IFREG | 0755) == archive_entry_mode(ae));
82         archive_entry_set_size(ae, 4);
83
84         assertA(0 == archive_write_header(a, ae));
85         archive_entry_free(ae);
86         assertA(4 == archive_write_data(a, "1234", 5));
87
88         /*
89          * Write a file with a name, filetype, and size.
90          */
91         assert((ae = archive_entry_new()) != NULL);
92         archive_entry_copy_pathname(ae, "name");
93         archive_entry_set_size(ae, 0);
94         archive_entry_set_filetype(ae, AE_IFREG);
95         assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
96         assert(archive_error_string(a) == NULL);
97         archive_entry_free(ae);
98
99         /*
100          * Write a file with a name and filetype but no size.
101          */
102         assert((ae = archive_entry_new()) != NULL);
103         archive_entry_copy_pathname(ae, "name");
104         archive_entry_unset_size(ae);
105         archive_entry_set_filetype(ae, AE_IFREG);
106         assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
107         assert(archive_error_string(a) != NULL);
108         archive_entry_free(ae);
109
110         /*
111          * Write a file with a name and size but no filetype.
112          */
113         assert((ae = archive_entry_new()) != NULL);
114         archive_entry_copy_pathname(ae, "name");
115         archive_entry_set_size(ae, 0);
116         assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
117         assert(archive_error_string(a) != NULL);
118         archive_entry_free(ae);
119
120         /*
121          * Write a file with a size and filetype but no name.
122          */
123         assert((ae = archive_entry_new()) != NULL);
124         archive_entry_set_size(ae, 0);
125         archive_entry_set_filetype(ae, AE_IFREG);
126         assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
127         assert(archive_error_string(a) != NULL);
128         archive_entry_free(ae);
129
130         /*
131          * Write a directory to it.
132          */
133         assert((ae = archive_entry_new()) != NULL);
134         archive_entry_set_mtime(ae, 11, 110);
135         archive_entry_copy_pathname(ae, "dir");
136         archive_entry_set_mode(ae, S_IFDIR | 0755);
137         archive_entry_set_size(ae, 512);
138
139         assertA(0 == archive_write_header(a, ae));
140         assertEqualInt(0, archive_entry_size(ae));
141         archive_entry_free(ae);
142         assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
143
144
145         /* Close out the archive. */
146         assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
147         assertEqualInt(ARCHIVE_OK, archive_write_free(a));
148
149         /*
150          * Damage the second entry to test the search-ahead recovery.
151          * TODO: Move the damage-recovery checking to a separate test;
152          * it doesn't really belong in this write test.
153          */
154         {
155                 int i;
156                 for (i = 80; i < 150; i++) {
157                         if (memcmp(buff + i, "07070", 5) == 0) {
158                                 damaged = 1;
159                                 buff[i] = 'X';
160                                 break;
161                         }
162                 }
163         }
164         failure("Unable to locate the second header for damage-recovery test.");
165         assert(damaged == 1);
166
167         /*
168          * Now, read the data back.
169          */
170         assert((a = archive_read_new()) != NULL);
171         assertA(0 == archive_read_support_format_all(a));
172         assertA(0 == archive_read_support_filter_all(a));
173         assertA(0 == archive_read_open_memory(a, buff, used));
174
175         if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) {
176                 archive_read_free(a);
177                 return;
178         }
179
180         assertEqualInt(1, archive_entry_mtime(ae));
181         /* Not the same as above: cpio doesn't store hi-res times. */
182         assert(0 == archive_entry_mtime_nsec(ae));
183         assert(0 == archive_entry_atime(ae));
184         assert(0 == archive_entry_ctime(ae));
185         assertEqualString("file", archive_entry_pathname(ae));
186         assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
187         assertEqualInt(8, archive_entry_size(ae));
188         assertA(8 == archive_read_data(a, filedata, 10));
189         assertEqualMem(filedata, "12345678", 8);
190
191         /*
192          * The second file can't be read because we damaged its header.
193          */
194
195         /*
196          * Read the third file back.
197          * ARCHIVE_WARN here because the damaged entry was skipped.
198          */
199         assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
200         assertEqualString("name", archive_entry_pathname(ae));
201
202         /*
203          * Read the dir entry back.
204          */
205         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
206         assertEqualInt(11, archive_entry_mtime(ae));
207         assert(0 == archive_entry_mtime_nsec(ae));
208         assert(0 == archive_entry_atime(ae));
209         assert(0 == archive_entry_ctime(ae));
210         assertEqualString("dir", archive_entry_pathname(ae));
211         assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae));
212         assertEqualInt(0, archive_entry_size(ae));
213         assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
214
215         /* Verify the end of the archive. */
216         assertEqualIntA(a, 1, archive_read_next_header(a, &ae));
217         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
218         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
219
220         free(buff);
221 }
222
223 static void
224 test_big_entries(int (*set_format)(struct archive *), int64_t size, int expected)
225 {
226         struct archive_entry *ae;
227         struct archive *a;
228         size_t buffsize = 1000000;
229         size_t used;
230         char *buff;
231
232         buff = malloc(buffsize);
233
234         /* Create a new archive in memory. */
235         assert((a = archive_write_new()) != NULL);
236         assertA(0 == (*set_format)(a));
237         assertA(0 == archive_write_add_filter_none(a));
238         assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
239
240         assert((ae = archive_entry_new()) != NULL);
241         archive_entry_copy_pathname(ae, "file");
242         archive_entry_set_size(ae, size);
243         archive_entry_set_filetype(ae, AE_IFREG);
244         assertEqualInt(expected, archive_write_header(a, ae));
245         if (expected != ARCHIVE_OK)
246                 assert(archive_error_string(a) != NULL);
247
248         archive_entry_free(ae);
249         archive_write_free(a);
250         free(buff);
251 }
252
253
254 DEFINE_TEST(test_write_format_cpio)
255 {
256         int64_t size_4g = ((int64_t)1) << 32;
257         int64_t size_8g = ((int64_t)1) << 33;
258
259         test_format(archive_write_set_format_cpio);
260         test_format(archive_write_set_format_cpio_newc);
261
262         test_big_entries(archive_write_set_format_cpio,
263             size_8g - 1, ARCHIVE_OK);
264         test_big_entries(archive_write_set_format_cpio,
265             size_8g, ARCHIVE_FAILED);
266         test_big_entries(archive_write_set_format_cpio_newc,
267             size_4g - 1, ARCHIVE_OK);
268         test_big_entries(archive_write_set_format_cpio_newc,
269             size_4g, ARCHIVE_FAILED);
270 }