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 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 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 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 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 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 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 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 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 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 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