]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_write_format_tar_sparse.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / libarchive / libarchive / test / test_write_format_tar_sparse.c
1 /*-
2  * Copyright (c) 2003-2010 Tim Kientzle
3  * Copyright (c) 2012 Michihiro NAKAJIMA
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include "test.h"
27 __FBSDID("$FreeBSD$");
28
29 static char buff[1000000];
30
31 static void
32 test_1(void)
33 {
34         struct archive_entry *ae;
35         struct archive *a;
36         size_t used;
37         size_t blocksize;
38         int64_t offset, length;
39         char *buff2;
40         size_t buff2_size = 0x13000;
41         char buff3[1024];
42         long i;
43
44         assert((buff2 = malloc(buff2_size)) != NULL);
45         /* Repeat the following for a variety of odd blocksizes. */
46         for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) {
47                 /* Create a new archive in memory. */
48                 assert((a = archive_write_new()) != NULL);
49                 assertEqualIntA(a, ARCHIVE_OK,
50                     archive_write_set_format_pax(a));
51                 assertEqualIntA(a, ARCHIVE_OK,
52                     archive_write_add_filter_none(a));
53                 assertEqualIntA(a, ARCHIVE_OK,
54                     archive_write_set_bytes_per_block(a, (int)blocksize));
55                 assertEqualIntA(a, ARCHIVE_OK,
56                     archive_write_set_bytes_in_last_block(a, (int)blocksize));
57                 assertEqualInt(blocksize,
58                     archive_write_get_bytes_in_last_block(a));
59                 assertEqualIntA(a, ARCHIVE_OK,
60                     archive_write_open_memory(a, buff, sizeof(buff), &used));
61                 assertEqualInt(blocksize,
62                     archive_write_get_bytes_in_last_block(a));
63
64                 /*
65                  * Write a file to it.
66                  */
67                 assert((ae = archive_entry_new()) != NULL);
68                 archive_entry_set_mtime(ae, 1, 10);
69                 assertEqualInt(1, archive_entry_mtime(ae));
70                 assertEqualInt(10, archive_entry_mtime_nsec(ae));
71                 archive_entry_copy_pathname(ae, "file");
72                 assertEqualString("file", archive_entry_pathname(ae));
73                 archive_entry_set_mode(ae, S_IFREG | 0755);
74                 assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
75                 archive_entry_set_size(ae, 0x81000);
76                 archive_entry_sparse_add_entry(ae, 0x10000, 0x1000);
77                 archive_entry_sparse_add_entry(ae, 0x80000, 0x1000);
78
79                 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
80                 archive_entry_free(ae);
81                 memset(buff2, 'a', buff2_size);
82                 for (i = 0; i < 0x81000;) {
83                         size_t ws = buff2_size;
84                         if (i + ws > 0x81000)
85                                 ws = 0x81000 - i;
86                         assertEqualInt(ws,
87                                 archive_write_data(a, buff2, ws));
88                         i += (long)ws;
89                 }
90
91                 /* Close out the archive. */
92                 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
93                 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
94
95                 /* This calculation gives "the smallest multiple of
96                  * the block size that is at least 11264 bytes". */
97                 failure("blocksize=%zu", blocksize);
98                 assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used);
99
100                 /*
101                  * Now, read the data back.
102                  */
103                 assert((a = archive_read_new()) != NULL);
104                 assertEqualIntA(a, ARCHIVE_OK,
105                     archive_read_support_format_all(a));
106                 assertEqualIntA(a, ARCHIVE_OK,
107                     archive_read_support_filter_all(a));
108                 assertEqualIntA(a, ARCHIVE_OK,
109                     archive_read_open_memory(a, buff, used));
110
111                 assertEqualIntA(a, ARCHIVE_OK,
112                     archive_read_next_header(a, &ae));
113
114                 assertEqualInt(1, archive_entry_mtime(ae));
115                 assertEqualInt(10, archive_entry_mtime_nsec(ae));
116                 assertEqualInt(0, archive_entry_atime(ae));
117                 assertEqualInt(0, archive_entry_ctime(ae));
118                 assertEqualString("file", archive_entry_pathname(ae));
119                 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
120                 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
121                 assertEqualInt(0x81000, archive_entry_size(ae));
122                 /* Verify sparse information. */
123                 assertEqualInt(2, archive_entry_sparse_reset(ae));
124                 assertEqualInt(0,
125                         archive_entry_sparse_next(ae, &offset, &length));
126                 assertEqualInt(0x10000, offset);
127                 assertEqualInt(0x1000, length);
128                 assertEqualInt(0,
129                         archive_entry_sparse_next(ae, &offset, &length));
130                 assertEqualInt(0x80000, offset);
131                 assertEqualInt(0x1000, length);
132                 /* Verify file contents. */
133                 memset(buff3, 0, sizeof(buff3));
134                 for (i = 0; i < 0x10000; i += 1024) {
135                         assertEqualInt(1024, archive_read_data(a, buff2, 1024));
136                         failure("Read data(0x%lx - 0x%lx) should be all zero",
137                             i, i + 1024);
138                         assertEqualMem(buff2, buff3, 1024);
139                 }
140                 memset(buff3, 'a', sizeof(buff3));
141                 for (i = 0x10000; i < 0x11000; i += 1024) {
142                         assertEqualInt(1024, archive_read_data(a, buff2, 1024));
143                         failure("Read data(0x%lx - 0x%lx) should be all 'a'",
144                             i, i + 1024);
145                         assertEqualMem(buff2, buff3, 1024);
146                 }
147                 memset(buff3, 0, sizeof(buff3));
148                 for (i = 0x11000; i < 0x80000; i += 1024) {
149                         assertEqualInt(1024, archive_read_data(a, buff2, 1024));
150                         failure("Read data(0x%lx - 0x%lx) should be all zero",
151                             i, i + 1024);
152                         assertEqualMem(buff2, buff3, 1024);
153                 }
154                 memset(buff3, 'a', sizeof(buff3));
155                 for (i = 0x80000; i < 0x81000; i += 1024) {
156                         assertEqualInt(1024, archive_read_data(a, buff2, 1024));
157                         failure("Read data(0x%lx - 0x%lx) should be all 'a'",
158                             i, i + 1024);
159                         assertEqualMem(buff2, buff3, 1024);
160                 }
161
162                 /* Verify the end of the archive. */
163                 assertEqualIntA(a, ARCHIVE_EOF,
164                     archive_read_next_header(a, &ae));
165                 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
166                 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
167         }
168         free(buff2);
169 }
170
171 /*
172  * Test for the case the full bytes of sparse file data is not written.
173  */
174 static void
175 test_2(void)
176 {
177         struct archive_entry *ae;
178         struct archive *a;
179         size_t used;
180         size_t blocksize = 20 * 512;
181         int64_t offset, length;
182         char *buff2;
183         size_t buff2_size = 0x11000;
184         char buff3[1024];
185         long i;
186
187         assert((buff2 = malloc(buff2_size)) != NULL);
188         /* Create a new archive in memory. */
189         assert((a = archive_write_new()) != NULL);
190         assertEqualIntA(a, ARCHIVE_OK,
191             archive_write_set_format_pax(a));
192         assertEqualIntA(a, ARCHIVE_OK,
193             archive_write_add_filter_none(a));
194         assertEqualIntA(a, ARCHIVE_OK,
195             archive_write_set_bytes_per_block(a, (int)blocksize));
196         assertEqualIntA(a, ARCHIVE_OK,
197             archive_write_set_bytes_in_last_block(a, (int)blocksize));
198         assertEqualInt(blocksize,
199             archive_write_get_bytes_in_last_block(a));
200         assertEqualIntA(a, ARCHIVE_OK,
201             archive_write_open_memory(a, buff, sizeof(buff), &used));
202         assertEqualInt(blocksize,
203             archive_write_get_bytes_in_last_block(a));
204
205         /*
206          * Write a file to it.
207          */
208         assert((ae = archive_entry_new()) != NULL);
209         archive_entry_set_mtime(ae, 1, 10);
210         assertEqualInt(1, archive_entry_mtime(ae));
211         assertEqualInt(10, archive_entry_mtime_nsec(ae));
212         archive_entry_copy_pathname(ae, "file");
213         assertEqualString("file", archive_entry_pathname(ae));
214         archive_entry_set_mode(ae, S_IFREG | 0755);
215         assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
216         archive_entry_set_size(ae, 0x81000);
217         archive_entry_sparse_add_entry(ae, 0x10000, 0x1000);
218         archive_entry_sparse_add_entry(ae, 0x80000, 0x1000);
219
220         assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
221         archive_entry_free(ae);
222         memset(buff2, 'a', buff2_size);
223         /* Write bytes less than it should be. */
224         assertEqualInt(buff2_size, archive_write_data(a, buff2, buff2_size));
225
226         /* Close out the archive. */
227         assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
228         assertEqualInt(ARCHIVE_OK, archive_write_free(a));
229
230         /* This calculation gives "the smallest multiple of
231          * the block size that is at least 11264 bytes". */
232         failure("blocksize=%zu", blocksize);
233         assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used);
234
235         /*
236          * Now, read the data back.
237          */
238         assert((a = archive_read_new()) != NULL);
239         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
240         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
241         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
242
243         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
244
245         assertEqualInt(1, archive_entry_mtime(ae));
246         assertEqualInt(10, archive_entry_mtime_nsec(ae));
247         assertEqualInt(0, archive_entry_atime(ae));
248         assertEqualInt(0, archive_entry_ctime(ae));
249         assertEqualString("file", archive_entry_pathname(ae));
250         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
251         assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
252         assertEqualInt(0x81000, archive_entry_size(ae));
253         /* Verify sparse information. */
254         assertEqualInt(2, archive_entry_sparse_reset(ae));
255         assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length));
256         assertEqualInt(0x10000, offset);
257         assertEqualInt(0x1000, length);
258         assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length));
259         assertEqualInt(0x80000, offset);
260         assertEqualInt(0x1000, length);
261         /* Verify file contents. */
262         memset(buff3, 0, sizeof(buff3));
263         for (i = 0; i < 0x10000; i += 1024) {
264                 assertEqualInt(1024, archive_read_data(a, buff2, 1024));
265                 failure("Read data(0x%lx - 0x%lx) should be all zero",
266                     i, i + 1024);
267                 assertEqualMem(buff2, buff3, 1024);
268         }
269         memset(buff3, 'a', sizeof(buff3));
270         for (i = 0x10000; i < 0x11000; i += 1024) {
271                 assertEqualInt(1024, archive_read_data(a, buff2, 1024));
272                 failure("Read data(0x%lx - 0x%lx) should be all 'a'",
273                     i, i + 1024);
274                 assertEqualMem(buff2, buff3, 1024);
275         }
276         memset(buff3, 0, sizeof(buff3));
277         for (i = 0x11000; i < 0x80000; i += 1024) {
278                 assertEqualInt(1024, archive_read_data(a, buff2, 1024));
279                 failure("Read data(0x%lx - 0x%lx) should be all zero",
280                     i, i + 1024);
281                 assertEqualMem(buff2, buff3, 1024);
282         }
283         memset(buff3, 0, sizeof(buff3));
284         for (i = 0x80000; i < 0x81000; i += 1024) {
285                 assertEqualInt(1024, archive_read_data(a, buff2, 1024));
286                 failure("Read data(0x%lx - 0x%lx) should be all 'a'",
287                     i, i + 1024);
288                 assertEqualMem(buff2, buff3, 1024);
289         }
290
291         /* Verify the end of the archive. */
292         assertEqualIntA(a, ARCHIVE_EOF,
293             archive_read_next_header(a, &ae));
294         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
295         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
296         free(buff2);
297 }
298
299 DEFINE_TEST(test_write_format_tar_sparse)
300 {
301         /* Test1: archiving sparse files. */
302         test_1();
303         /* Test2: incompletely archiving sparse files. */
304         test_2();
305 }