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