xref: /freebsd/contrib/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c (revision bd66c1b43e33540205dbc1187c2f2a15c58b57ba)
1 /*-
2  * Copyright (c) 2011 Tim Kientzle
3  * Copyright (c) 2011-2012 Andres Mejia
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 
27 #include "test.h"
28 
29 #if defined(_WIN32) && !defined(__CYGWIN__)
30 #define open _open
31 #define close _close
32 #define read _read
33 #if !defined(__BORLANDC__)
34 #ifdef lseek
35 #undef lseek
36 #endif
37 #define lseek(f, o, w) _lseek(f, (long)(o), (int)(w))
38 #endif
39 #endif
40 
41 static void
test_splitted_file(void)42 test_splitted_file(void)
43 {
44   char buff[64];
45   static const char *reffiles[] =
46   {
47     "test_read_splitted_rar_aa",
48     "test_read_splitted_rar_ab",
49     "test_read_splitted_rar_ac",
50     "test_read_splitted_rar_ad",
51     NULL
52   };
53   const char test_txt[] = "test text document\r\n";
54   int size = sizeof(test_txt)-1;
55   struct archive_entry *ae;
56   struct archive *a;
57 
58   extract_reference_files(reffiles);
59   assert((a = archive_read_new()) != NULL);
60   assertA(0 == archive_read_support_filter_all(a));
61   assertA(0 == archive_read_support_format_all(a));
62   assertA(0 == archive_read_open_filenames(a, reffiles, 10240));
63 
64   /* First header. */
65   assertA(0 == archive_read_next_header(a, &ae));
66   assertEqualString("test.txt", archive_entry_pathname(ae));
67   assertA((int)archive_entry_mtime(ae));
68   assertA((int)archive_entry_ctime(ae));
69   assertA((int)archive_entry_atime(ae));
70   assertEqualInt(20, archive_entry_size(ae));
71   assertEqualInt(33188, archive_entry_mode(ae));
72   assertA(size == archive_read_data(a, buff, size));
73   assertEqualMem(buff, test_txt, size);
74 
75   /* Second header. */
76   assertA(0 == archive_read_next_header(a, &ae));
77   assertEqualString("testlink", archive_entry_pathname(ae));
78   assertA((int)archive_entry_mtime(ae));
79   assertA((int)archive_entry_ctime(ae));
80   assertA((int)archive_entry_atime(ae));
81   assertEqualInt(0, archive_entry_size(ae));
82   assertEqualInt(41471, archive_entry_mode(ae));
83   assertEqualString("test.txt", archive_entry_symlink(ae));
84   assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
85 
86   /* Third header. */
87   assertA(0 == archive_read_next_header(a, &ae));
88   assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
89   assertA((int)archive_entry_mtime(ae));
90   assertA((int)archive_entry_ctime(ae));
91   assertA((int)archive_entry_atime(ae));
92   assertEqualInt(20, archive_entry_size(ae));
93   assertEqualInt(33188, archive_entry_mode(ae));
94   assertA(size == archive_read_data(a, buff, size));
95   assertEqualMem(buff, test_txt, size);
96 
97   /* Fourth header. */
98   assertA(0 == archive_read_next_header(a, &ae));
99   assertEqualString("testdir", archive_entry_pathname(ae));
100   assertA((int)archive_entry_mtime(ae));
101   assertA((int)archive_entry_ctime(ae));
102   assertA((int)archive_entry_atime(ae));
103   assertEqualInt(0, archive_entry_size(ae));
104   assertEqualInt(16877, archive_entry_mode(ae));
105 
106   /* Fifth header. */
107   assertA(0 == archive_read_next_header(a, &ae));
108   assertEqualString("testemptydir", archive_entry_pathname(ae));
109   assertA((int)archive_entry_mtime(ae));
110   assertA((int)archive_entry_ctime(ae));
111   assertA((int)archive_entry_atime(ae));
112   assertEqualInt(0, archive_entry_size(ae));
113   assertEqualInt(16877, archive_entry_mode(ae));
114 
115   /* Test EOF */
116   assertA(1 == archive_read_next_header(a, &ae));
117   assertEqualInt(5, archive_file_count(a));
118   assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
119   assertEqualInt(ARCHIVE_OK, archive_read_free(a));
120 }
121 
122 static void
test_large_splitted_file(void)123 test_large_splitted_file(void)
124 {
125   static const char *reffiles[] =
126   {
127     "test_read_large_splitted_rar_aa",
128     "test_read_large_splitted_rar_ab",
129     "test_read_large_splitted_rar_ac",
130     "test_read_large_splitted_rar_ad",
131     "test_read_large_splitted_rar_ae",
132     NULL
133   };
134   const char test_txt[] = "gin-bottom: 0in\"><BR>\n</P>\n</BODY>\n</HTML>";
135   int size = 241647978, offset = 0;
136   char buff[64];
137   struct archive_entry *ae;
138   struct archive *a;
139 
140   extract_reference_files(reffiles);
141   assert((a = archive_read_new()) != NULL);
142   assertA(0 == archive_read_support_filter_all(a));
143   assertA(0 == archive_read_support_format_all(a));
144   assertA(0 == archive_read_open_filenames(a, reffiles, 10240));
145 
146   /* First header. */
147   assertA(0 == archive_read_next_header(a, &ae));
148   assertEqualString("ppmd_lzss_conversion_test.txt",
149                     archive_entry_pathname(ae));
150   assertA((int)archive_entry_mtime(ae));
151   assertA((int)archive_entry_ctime(ae));
152   assertA((int)archive_entry_atime(ae));
153   assertEqualInt(size, archive_entry_size(ae));
154   assertEqualInt(33188, archive_entry_mode(ae));
155   while (offset + (int)sizeof(buff) < size)
156   {
157     assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff)));
158     offset += sizeof(buff);
159   }
160   assertA(size - offset == archive_read_data(a, buff, size - offset));
161   assertEqualMem(buff, test_txt, size - offset);
162 
163   /* Test EOF */
164   assertA(1 == archive_read_next_header(a, &ae));
165   assertEqualInt(1, archive_file_count(a));
166   assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
167   assertEqualInt(ARCHIVE_OK, archive_read_free(a));
168 }
169 
170 #define BLOCK_SIZE 10240
171 struct mydata {
172   char *filename;
173   void *buffer;
174   int fd;
175 };
176 
177 static int
file_open(struct archive * a,void * data)178 file_open(struct archive *a, void *data)
179 {
180   struct mydata *mydata = (struct mydata *)data;
181   (void)a;
182   if (mydata->fd < 0)
183   {
184     mydata->fd = open(mydata->filename, O_RDONLY | O_BINARY);
185     if (mydata->fd >= 0)
186     {
187       if ((mydata->buffer = calloc(BLOCK_SIZE, 1)) == NULL)
188         return (ARCHIVE_FAILED);
189     }
190   }
191   return (ARCHIVE_OK);
192 }
193 static ssize_t
file_read(struct archive * a,void * data,const void ** buff)194 file_read(struct archive *a, void *data, const void **buff)
195 {
196   struct mydata *mydata = (struct mydata *)data;
197   (void)a;
198   *buff = mydata->buffer;
199   return read(mydata->fd, mydata->buffer, BLOCK_SIZE);
200 }
201 static int64_t
file_skip(struct archive * a,void * data,int64_t request)202 file_skip(struct archive *a, void *data, int64_t request)
203 {
204   struct mydata *mydata = (struct mydata *)data;
205   int64_t result = lseek(mydata->fd, SEEK_CUR, request);
206   if (result >= 0)
207     return result;
208   archive_set_error(a, errno, "Error seeking in '%s'", mydata->filename);
209   return -1;
210 }
211 static int
file_switch(struct archive * a,void * data1,void * data2)212 file_switch(struct archive *a, void *data1, void *data2)
213 {
214   struct mydata *mydata1 = (struct mydata *)data1;
215   struct mydata *mydata2 = (struct mydata *)data2;
216   int r = (ARCHIVE_OK);
217 
218   (void)a;
219   if (mydata1 && mydata1->fd >= 0)
220   {
221     close(mydata1->fd);
222     free(mydata1->buffer);
223     mydata1->buffer = NULL;
224     mydata1->fd = -1;
225   }
226   if (mydata2)
227   {
228     r = file_open(a, mydata2);
229   }
230   return (r);
231 }
232 static int
file_close(struct archive * a,void * data)233 file_close(struct archive *a, void *data)
234 {
235   struct mydata *mydata = (struct mydata *)data;
236   if (mydata == NULL)
237     return (ARCHIVE_FATAL);
238   file_switch(a, mydata, NULL);
239   free(mydata->filename);
240   free(mydata);
241   return (ARCHIVE_OK);
242 }
243 static int64_t
file_seek(struct archive * a,void * data,int64_t request,int whence)244 file_seek(struct archive *a, void *data, int64_t request, int whence)
245 {
246   struct mydata *mine = (struct mydata *)data;
247   int64_t r;
248 
249   (void)a;
250   r = lseek(mine->fd, request, whence);
251   if (r >= 0)
252     return r;
253   return (ARCHIVE_FATAL);
254 }
255 
256 static void
test_customized_multiple_data_objects(void)257 test_customized_multiple_data_objects(void)
258 {
259   char buff[64];
260   static const char *reffiles[] =
261   {
262     "test_read_splitted_rar_aa",
263     "test_read_splitted_rar_ab",
264     "test_read_splitted_rar_ac",
265     "test_read_splitted_rar_ad",
266     NULL
267   };
268   const char test_txt[] = "test text document\r\n";
269   int size = sizeof(test_txt)-1;
270   struct archive_entry *ae;
271   struct archive *a;
272   struct mydata *mydata;
273   const char *filename = *reffiles;
274   int i;
275 
276   extract_reference_files(reffiles);
277   assert((a = archive_read_new()) != NULL);
278   assertA(0 == archive_read_support_filter_all(a));
279   assertA(0 == archive_read_support_format_all(a));
280 
281   for (i = 0; filename != NULL;)
282   {
283     assert((mydata = calloc(1, sizeof(*mydata))) != NULL);
284     if (mydata == NULL) {
285       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
286       return;
287     }
288     assert((mydata->filename = strdup(filename)) != NULL);
289     mydata->fd = -1;
290     filename = reffiles[++i];
291     assertA(0 == archive_read_append_callback_data(a, mydata));
292   }
293   assertA(0 == archive_read_set_open_callback(a, file_open));
294   assertA(0 == archive_read_set_read_callback(a, file_read));
295   assertA(0 == archive_read_set_skip_callback(a, file_skip));
296   assertA(0 == archive_read_set_close_callback(a, file_close));
297   assertA(0 == archive_read_set_switch_callback(a, file_switch));
298   assertA(0 == archive_read_set_seek_callback(a, file_seek));
299   assertA(0 == archive_read_open1(a));
300 
301   /* First header. */
302   assertA(0 == archive_read_next_header(a, &ae));
303   assertEqualString("test.txt", archive_entry_pathname(ae));
304   assertA((int)archive_entry_mtime(ae));
305   assertA((int)archive_entry_ctime(ae));
306   assertA((int)archive_entry_atime(ae));
307   assertEqualInt(20, archive_entry_size(ae));
308   assertEqualInt(33188, archive_entry_mode(ae));
309   assertA(size == archive_read_data(a, buff, size));
310   assertEqualMem(buff, test_txt, size);
311 
312   /* Second header. */
313   assertA(0 == archive_read_next_header(a, &ae));
314   assertEqualString("testlink", archive_entry_pathname(ae));
315   assertA((int)archive_entry_mtime(ae));
316   assertA((int)archive_entry_ctime(ae));
317   assertA((int)archive_entry_atime(ae));
318   assertEqualInt(0, archive_entry_size(ae));
319   assertEqualInt(41471, archive_entry_mode(ae));
320   assertEqualString("test.txt", archive_entry_symlink(ae));
321   assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
322 
323   /* Third header. */
324   assertA(0 == archive_read_next_header(a, &ae));
325   assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
326   assertA((int)archive_entry_mtime(ae));
327   assertA((int)archive_entry_ctime(ae));
328   assertA((int)archive_entry_atime(ae));
329   assertEqualInt(20, archive_entry_size(ae));
330   assertEqualInt(33188, archive_entry_mode(ae));
331   assertA(size == archive_read_data(a, buff, size));
332   assertEqualMem(buff, test_txt, size);
333 
334   /* Fourth header. */
335   assertA(0 == archive_read_next_header(a, &ae));
336   assertEqualString("testdir", archive_entry_pathname(ae));
337   assertA((int)archive_entry_mtime(ae));
338   assertA((int)archive_entry_ctime(ae));
339   assertA((int)archive_entry_atime(ae));
340   assertEqualInt(0, archive_entry_size(ae));
341   assertEqualInt(16877, archive_entry_mode(ae));
342 
343   /* Fifth header. */
344   assertA(0 == archive_read_next_header(a, &ae));
345   assertEqualString("testemptydir", archive_entry_pathname(ae));
346   assertA((int)archive_entry_mtime(ae));
347   assertA((int)archive_entry_ctime(ae));
348   assertA((int)archive_entry_atime(ae));
349   assertEqualInt(0, archive_entry_size(ae));
350   assertEqualInt(16877, archive_entry_mode(ae));
351 
352   /* Test EOF */
353   assertA(1 == archive_read_next_header(a, &ae));
354   assertEqualInt(5, archive_file_count(a));
355   assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
356   assertEqualInt(ARCHIVE_OK, archive_read_free(a));
357 }
358 
DEFINE_TEST(test_archive_read_multiple_data_objects)359 DEFINE_TEST(test_archive_read_multiple_data_objects)
360 {
361   test_splitted_file();
362   test_large_splitted_file();
363   test_customized_multiple_data_objects();
364 }
365