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