OLD | NEW |
(Empty) | |
| 1 /////////////////////////////////////////////////////////////////////////////// |
| 2 // |
| 3 /// \file test_index.c |
| 4 /// \brief Tests functions handling the lzma_index structure |
| 5 // |
| 6 // Author: Lasse Collin |
| 7 // |
| 8 // This file has been put into the public domain. |
| 9 // You can do whatever you want with this file. |
| 10 // |
| 11 /////////////////////////////////////////////////////////////////////////////// |
| 12 |
| 13 #include "tests.h" |
| 14 |
| 15 #define MEMLIMIT (LZMA_VLI_C(1) << 20) |
| 16 |
| 17 #define SMALL_COUNT 3 |
| 18 #define BIG_COUNT 5555 |
| 19 |
| 20 |
| 21 static lzma_index * |
| 22 create_empty(void) |
| 23 { |
| 24 lzma_index *i = lzma_index_init(NULL); |
| 25 expect(i != NULL); |
| 26 return i; |
| 27 } |
| 28 |
| 29 |
| 30 static lzma_index * |
| 31 create_small(void) |
| 32 { |
| 33 lzma_index *i = lzma_index_init(NULL); |
| 34 expect(i != NULL); |
| 35 expect(lzma_index_append(i, NULL, 101, 555) == LZMA_OK); |
| 36 expect(lzma_index_append(i, NULL, 602, 777) == LZMA_OK); |
| 37 expect(lzma_index_append(i, NULL, 804, 999) == LZMA_OK); |
| 38 return i; |
| 39 } |
| 40 |
| 41 |
| 42 static lzma_index * |
| 43 create_big(void) |
| 44 { |
| 45 lzma_index *i = lzma_index_init(NULL); |
| 46 expect(i != NULL); |
| 47 |
| 48 lzma_vli total_size = 0; |
| 49 lzma_vli uncompressed_size = 0; |
| 50 |
| 51 // Add pseudo-random sizes (but always the same size values). |
| 52 uint32_t n = 11; |
| 53 for (size_t j = 0; j < BIG_COUNT; ++j) { |
| 54 n = 7019 * n + 7607; |
| 55 const uint32_t t = n * 3011; |
| 56 expect(lzma_index_append(i, NULL, t, n) == LZMA_OK); |
| 57 total_size += (t + 3) & ~LZMA_VLI_C(3); |
| 58 uncompressed_size += n; |
| 59 } |
| 60 |
| 61 expect(lzma_index_block_count(i) == BIG_COUNT); |
| 62 expect(lzma_index_total_size(i) == total_size); |
| 63 expect(lzma_index_uncompressed_size(i) == uncompressed_size); |
| 64 expect(lzma_index_total_size(i) + lzma_index_size(i) |
| 65 + 2 * LZMA_STREAM_HEADER_SIZE |
| 66 == lzma_index_stream_size(i)); |
| 67 |
| 68 return i; |
| 69 } |
| 70 |
| 71 |
| 72 static bool |
| 73 is_equal(const lzma_index *a, const lzma_index *b) |
| 74 { |
| 75 // Compare only the Stream and Block sizes and offsets. |
| 76 lzma_index_iter ra, rb; |
| 77 lzma_index_iter_init(&ra, a); |
| 78 lzma_index_iter_init(&rb, b); |
| 79 |
| 80 while (true) { |
| 81 bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY); |
| 82 bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY); |
| 83 if (reta) |
| 84 return !(reta ^ retb); |
| 85 |
| 86 if (ra.stream.number != rb.stream.number |
| 87 || ra.stream.block_count |
| 88 != rb.stream.block_count |
| 89 || ra.stream.compressed_offset |
| 90 != rb.stream.compressed_offset |
| 91 || ra.stream.uncompressed_offset |
| 92 != rb.stream.uncompressed_offset |
| 93 || ra.stream.compressed_size |
| 94 != rb.stream.compressed_size |
| 95 || ra.stream.uncompressed_size |
| 96 != rb.stream.uncompressed_size |
| 97 || ra.stream.padding |
| 98 != rb.stream.padding) |
| 99 return false; |
| 100 |
| 101 if (ra.stream.block_count == 0) |
| 102 continue; |
| 103 |
| 104 if (ra.block.number_in_file != rb.block.number_in_file |
| 105 || ra.block.compressed_file_offset |
| 106 != rb.block.compressed_file_offset |
| 107 || ra.block.uncompressed_file_offset |
| 108 != rb.block.uncompressed_file_offset |
| 109 || ra.block.number_in_stream |
| 110 != rb.block.number_in_stream |
| 111 || ra.block.compressed_stream_offset |
| 112 != rb.block.compressed_stream_offset |
| 113 || ra.block.uncompressed_stream_offset |
| 114 != rb.block.uncompressed_stream_offset |
| 115 || ra.block.uncompressed_size |
| 116 != rb.block.uncompressed_size |
| 117 || ra.block.unpadded_size |
| 118 != rb.block.unpadded_size |
| 119 || ra.block.total_size |
| 120 != rb.block.total_size) |
| 121 return false; |
| 122 } |
| 123 } |
| 124 |
| 125 |
| 126 static void |
| 127 test_equal(void) |
| 128 { |
| 129 lzma_index *a = create_empty(); |
| 130 lzma_index *b = create_small(); |
| 131 lzma_index *c = create_big(); |
| 132 expect(a && b && c); |
| 133 |
| 134 expect(is_equal(a, a)); |
| 135 expect(is_equal(b, b)); |
| 136 expect(is_equal(c, c)); |
| 137 |
| 138 expect(!is_equal(a, b)); |
| 139 expect(!is_equal(a, c)); |
| 140 expect(!is_equal(b, c)); |
| 141 |
| 142 lzma_index_end(a, NULL); |
| 143 lzma_index_end(b, NULL); |
| 144 lzma_index_end(c, NULL); |
| 145 } |
| 146 |
| 147 |
| 148 static void |
| 149 test_overflow(void) |
| 150 { |
| 151 // Integer overflow tests |
| 152 lzma_index *i = create_empty(); |
| 153 |
| 154 expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234) |
| 155 == LZMA_DATA_ERROR); |
| 156 |
| 157 // TODO |
| 158 |
| 159 lzma_index_end(i, NULL); |
| 160 } |
| 161 |
| 162 |
| 163 static void |
| 164 test_copy(const lzma_index *i) |
| 165 { |
| 166 lzma_index *d = lzma_index_dup(i, NULL); |
| 167 expect(d != NULL); |
| 168 expect(is_equal(i, d)); |
| 169 lzma_index_end(d, NULL); |
| 170 } |
| 171 |
| 172 |
| 173 static void |
| 174 test_read(lzma_index *i) |
| 175 { |
| 176 lzma_index_iter r; |
| 177 lzma_index_iter_init(&r, i); |
| 178 |
| 179 // Try twice so we see that rewinding works. |
| 180 for (size_t j = 0; j < 2; ++j) { |
| 181 lzma_vli total_size = 0; |
| 182 lzma_vli uncompressed_size = 0; |
| 183 lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE; |
| 184 lzma_vli uncompressed_offset = 0; |
| 185 uint32_t count = 0; |
| 186 |
| 187 while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)) { |
| 188 ++count; |
| 189 |
| 190 total_size += r.block.total_size; |
| 191 uncompressed_size += r.block.uncompressed_size; |
| 192 |
| 193 expect(r.block.compressed_file_offset |
| 194 == stream_offset); |
| 195 expect(r.block.uncompressed_file_offset |
| 196 == uncompressed_offset); |
| 197 |
| 198 stream_offset += r.block.total_size; |
| 199 uncompressed_offset += r.block.uncompressed_size; |
| 200 } |
| 201 |
| 202 expect(lzma_index_total_size(i) == total_size); |
| 203 expect(lzma_index_uncompressed_size(i) == uncompressed_size); |
| 204 expect(lzma_index_block_count(i) == count); |
| 205 |
| 206 lzma_index_iter_rewind(&r); |
| 207 } |
| 208 } |
| 209 |
| 210 |
| 211 static void |
| 212 test_code(lzma_index *i) |
| 213 { |
| 214 const size_t alloc_size = 128 * 1024; |
| 215 uint8_t *buf = malloc(alloc_size); |
| 216 expect(buf != NULL); |
| 217 |
| 218 // Encode |
| 219 lzma_stream strm = LZMA_STREAM_INIT; |
| 220 expect(lzma_index_encoder(&strm, i) == LZMA_OK); |
| 221 const lzma_vli index_size = lzma_index_size(i); |
| 222 succeed(coder_loop(&strm, NULL, 0, buf, index_size, |
| 223 LZMA_STREAM_END, LZMA_RUN)); |
| 224 |
| 225 // Decode |
| 226 lzma_index *d; |
| 227 expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK); |
| 228 expect(d == NULL); |
| 229 succeed(decoder_loop(&strm, buf, index_size)); |
| 230 |
| 231 expect(is_equal(i, d)); |
| 232 |
| 233 lzma_index_end(d, NULL); |
| 234 lzma_end(&strm); |
| 235 |
| 236 // Decode with hashing |
| 237 lzma_index_hash *h = lzma_index_hash_init(NULL, NULL); |
| 238 expect(h != NULL); |
| 239 lzma_index_iter r; |
| 240 lzma_index_iter_init(&r, i); |
| 241 while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)) |
| 242 expect(lzma_index_hash_append(h, r.block.unpadded_size, |
| 243 r.block.uncompressed_size) == LZMA_OK); |
| 244 size_t pos = 0; |
| 245 while (pos < index_size - 1) |
| 246 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1) |
| 247 == LZMA_OK); |
| 248 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1) |
| 249 == LZMA_STREAM_END); |
| 250 |
| 251 lzma_index_hash_end(h, NULL); |
| 252 |
| 253 // Encode buffer |
| 254 size_t buf_pos = 1; |
| 255 expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size) |
| 256 == LZMA_BUF_ERROR); |
| 257 expect(buf_pos == 1); |
| 258 |
| 259 succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1)); |
| 260 expect(buf_pos == index_size + 1); |
| 261 |
| 262 // Decode buffer |
| 263 buf_pos = 1; |
| 264 uint64_t memlimit = MEMLIMIT; |
| 265 expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos, |
| 266 index_size) == LZMA_DATA_ERROR); |
| 267 expect(buf_pos == 1); |
| 268 expect(d == NULL); |
| 269 |
| 270 succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos, |
| 271 index_size + 1)); |
| 272 expect(buf_pos == index_size + 1); |
| 273 expect(is_equal(i, d)); |
| 274 |
| 275 lzma_index_end(d, NULL); |
| 276 |
| 277 free(buf); |
| 278 } |
| 279 |
| 280 |
| 281 static void |
| 282 test_many(lzma_index *i) |
| 283 { |
| 284 test_copy(i); |
| 285 test_read(i); |
| 286 test_code(i); |
| 287 } |
| 288 |
| 289 |
| 290 static void |
| 291 test_cat(void) |
| 292 { |
| 293 lzma_index *a, *b, *c; |
| 294 lzma_index_iter r; |
| 295 |
| 296 // Empty Indexes |
| 297 a = create_empty(); |
| 298 b = create_empty(); |
| 299 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 300 expect(lzma_index_block_count(a) == 0); |
| 301 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8); |
| 302 expect(lzma_index_file_size(a) |
| 303 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8)); |
| 304 lzma_index_iter_init(&r, a); |
| 305 expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)); |
| 306 |
| 307 b = create_empty(); |
| 308 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 309 expect(lzma_index_block_count(a) == 0); |
| 310 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8); |
| 311 expect(lzma_index_file_size(a) |
| 312 == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8)); |
| 313 |
| 314 b = create_empty(); |
| 315 c = create_empty(); |
| 316 expect(lzma_index_stream_padding(b, 4) == LZMA_OK); |
| 317 expect(lzma_index_cat(b, c, NULL) == LZMA_OK); |
| 318 expect(lzma_index_block_count(b) == 0); |
| 319 expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8); |
| 320 expect(lzma_index_file_size(b) |
| 321 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4); |
| 322 |
| 323 expect(lzma_index_stream_padding(a, 8) == LZMA_OK); |
| 324 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 325 expect(lzma_index_block_count(a) == 0); |
| 326 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8); |
| 327 expect(lzma_index_file_size(a) |
| 328 == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8); |
| 329 |
| 330 expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)); |
| 331 lzma_index_iter_rewind(&r); |
| 332 expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)); |
| 333 lzma_index_end(a, NULL); |
| 334 |
| 335 // Small Indexes |
| 336 a = create_small(); |
| 337 lzma_vli stream_size = lzma_index_stream_size(a); |
| 338 lzma_index_iter_init(&r, a); |
| 339 for (int i = SMALL_COUNT; i >= 0; --i) |
| 340 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 341 ^ (i == 0)); |
| 342 |
| 343 b = create_small(); |
| 344 expect(lzma_index_stream_padding(a, 4) == LZMA_OK); |
| 345 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 346 expect(lzma_index_file_size(a) == stream_size * 2 + 4); |
| 347 expect(lzma_index_stream_size(a) > stream_size); |
| 348 expect(lzma_index_stream_size(a) < stream_size * 2); |
| 349 for (int i = SMALL_COUNT; i >= 0; --i) |
| 350 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 351 ^ (i == 0)); |
| 352 |
| 353 lzma_index_iter_rewind(&r); |
| 354 for (int i = SMALL_COUNT * 2; i >= 0; --i) |
| 355 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 356 ^ (i == 0)); |
| 357 |
| 358 b = create_small(); |
| 359 c = create_small(); |
| 360 expect(lzma_index_stream_padding(b, 8) == LZMA_OK); |
| 361 expect(lzma_index_cat(b, c, NULL) == LZMA_OK); |
| 362 expect(lzma_index_stream_padding(a, 12) == LZMA_OK); |
| 363 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 364 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12); |
| 365 |
| 366 expect(lzma_index_block_count(a) == SMALL_COUNT * 4); |
| 367 for (int i = SMALL_COUNT * 2; i >= 0; --i) |
| 368 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 369 ^ (i == 0)); |
| 370 |
| 371 lzma_index_iter_rewind(&r); |
| 372 for (int i = SMALL_COUNT * 4; i >= 0; --i) |
| 373 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 374 ^ (i == 0)); |
| 375 |
| 376 lzma_index_end(a, NULL); |
| 377 |
| 378 // Mix of empty and small |
| 379 a = create_empty(); |
| 380 b = create_small(); |
| 381 expect(lzma_index_stream_padding(a, 4) == LZMA_OK); |
| 382 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 383 lzma_index_iter_init(&r, a); |
| 384 for (int i = SMALL_COUNT; i >= 0; --i) |
| 385 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 386 ^ (i == 0)); |
| 387 |
| 388 lzma_index_end(a, NULL); |
| 389 |
| 390 // Big Indexes |
| 391 a = create_big(); |
| 392 stream_size = lzma_index_stream_size(a); |
| 393 b = create_big(); |
| 394 expect(lzma_index_stream_padding(a, 4) == LZMA_OK); |
| 395 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 396 expect(lzma_index_file_size(a) == stream_size * 2 + 4); |
| 397 expect(lzma_index_stream_size(a) > stream_size); |
| 398 expect(lzma_index_stream_size(a) < stream_size * 2); |
| 399 |
| 400 b = create_big(); |
| 401 c = create_big(); |
| 402 expect(lzma_index_stream_padding(b, 8) == LZMA_OK); |
| 403 expect(lzma_index_cat(b, c, NULL) == LZMA_OK); |
| 404 expect(lzma_index_stream_padding(a, 12) == LZMA_OK); |
| 405 expect(lzma_index_cat(a, b, NULL) == LZMA_OK); |
| 406 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12); |
| 407 |
| 408 lzma_index_iter_init(&r, a); |
| 409 for (int i = BIG_COUNT * 4; i >= 0; --i) |
| 410 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK) |
| 411 ^ (i == 0)); |
| 412 |
| 413 lzma_index_end(a, NULL); |
| 414 } |
| 415 |
| 416 |
| 417 static void |
| 418 test_locate(void) |
| 419 { |
| 420 lzma_index *i = lzma_index_init(NULL); |
| 421 expect(i != NULL); |
| 422 lzma_index_iter r; |
| 423 lzma_index_iter_init(&r, i); |
| 424 |
| 425 // Cannot locate anything from an empty Index. |
| 426 expect(lzma_index_iter_locate(&r, 0)); |
| 427 expect(lzma_index_iter_locate(&r, 555)); |
| 428 |
| 429 // One empty Record: nothing is found since there's no uncompressed |
| 430 // data. |
| 431 expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK); |
| 432 expect(lzma_index_iter_locate(&r, 0)); |
| 433 |
| 434 // Non-empty Record and we can find something. |
| 435 expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK); |
| 436 expect(!lzma_index_iter_locate(&r, 0)); |
| 437 expect(r.block.total_size == 32); |
| 438 expect(r.block.uncompressed_size == 5); |
| 439 expect(r.block.compressed_file_offset |
| 440 == LZMA_STREAM_HEADER_SIZE + 16); |
| 441 expect(r.block.uncompressed_file_offset == 0); |
| 442 |
| 443 // Still cannot find anything past the end. |
| 444 expect(lzma_index_iter_locate(&r, 5)); |
| 445 |
| 446 // Add the third Record. |
| 447 expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK); |
| 448 |
| 449 expect(!lzma_index_iter_locate(&r, 0)); |
| 450 expect(r.block.total_size == 32); |
| 451 expect(r.block.uncompressed_size == 5); |
| 452 expect(r.block.compressed_file_offset |
| 453 == LZMA_STREAM_HEADER_SIZE + 16); |
| 454 expect(r.block.uncompressed_file_offset == 0); |
| 455 |
| 456 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)); |
| 457 expect(r.block.total_size == 40); |
| 458 expect(r.block.uncompressed_size == 11); |
| 459 expect(r.block.compressed_file_offset |
| 460 == LZMA_STREAM_HEADER_SIZE + 16 + 32); |
| 461 expect(r.block.uncompressed_file_offset == 5); |
| 462 |
| 463 expect(!lzma_index_iter_locate(&r, 2)); |
| 464 expect(r.block.total_size == 32); |
| 465 expect(r.block.uncompressed_size == 5); |
| 466 expect(r.block.compressed_file_offset |
| 467 == LZMA_STREAM_HEADER_SIZE + 16); |
| 468 expect(r.block.uncompressed_file_offset == 0); |
| 469 |
| 470 expect(!lzma_index_iter_locate(&r, 5)); |
| 471 expect(r.block.total_size == 40); |
| 472 expect(r.block.uncompressed_size == 11); |
| 473 expect(r.block.compressed_file_offset |
| 474 == LZMA_STREAM_HEADER_SIZE + 16 + 32); |
| 475 expect(r.block.uncompressed_file_offset == 5); |
| 476 |
| 477 expect(!lzma_index_iter_locate(&r, 5 + 11 - 1)); |
| 478 expect(r.block.total_size == 40); |
| 479 expect(r.block.uncompressed_size == 11); |
| 480 expect(r.block.compressed_file_offset |
| 481 == LZMA_STREAM_HEADER_SIZE + 16 + 32); |
| 482 expect(r.block.uncompressed_file_offset == 5); |
| 483 |
| 484 expect(lzma_index_iter_locate(&r, 5 + 11)); |
| 485 expect(lzma_index_iter_locate(&r, 5 + 15)); |
| 486 |
| 487 // Large Index |
| 488 lzma_index_end(i, NULL); |
| 489 i = lzma_index_init(NULL); |
| 490 expect(i != NULL); |
| 491 lzma_index_iter_init(&r, i); |
| 492 |
| 493 for (size_t n = 4; n <= 4 * 5555; n += 4) |
| 494 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK); |
| 495 |
| 496 expect(lzma_index_block_count(i) == 5555); |
| 497 |
| 498 // First Record |
| 499 expect(!lzma_index_iter_locate(&r, 0)); |
| 500 expect(r.block.total_size == 4 + 8); |
| 501 expect(r.block.uncompressed_size == 4); |
| 502 expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE); |
| 503 expect(r.block.uncompressed_file_offset == 0); |
| 504 |
| 505 expect(!lzma_index_iter_locate(&r, 3)); |
| 506 expect(r.block.total_size == 4 + 8); |
| 507 expect(r.block.uncompressed_size == 4); |
| 508 expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE); |
| 509 expect(r.block.uncompressed_file_offset == 0); |
| 510 |
| 511 // Second Record |
| 512 expect(!lzma_index_iter_locate(&r, 4)); |
| 513 expect(r.block.total_size == 2 * 4 + 8); |
| 514 expect(r.block.uncompressed_size == 2 * 4); |
| 515 expect(r.block.compressed_file_offset |
| 516 == LZMA_STREAM_HEADER_SIZE + 4 + 8); |
| 517 expect(r.block.uncompressed_file_offset == 4); |
| 518 |
| 519 // Last Record |
| 520 expect(!lzma_index_iter_locate( |
| 521 &r, lzma_index_uncompressed_size(i) - 1)); |
| 522 expect(r.block.total_size == 4 * 5555 + 8); |
| 523 expect(r.block.uncompressed_size == 4 * 5555); |
| 524 expect(r.block.compressed_file_offset == lzma_index_total_size(i) |
| 525 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8); |
| 526 expect(r.block.uncompressed_file_offset |
| 527 == lzma_index_uncompressed_size(i) - 4 * 5555); |
| 528 |
| 529 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in |
| 530 // liblzma/common/index.c. |
| 531 const size_t group_multiple = 256 * 4; |
| 532 const size_t radius = 8; |
| 533 const size_t start = group_multiple - radius; |
| 534 lzma_vli ubase = 0; |
| 535 lzma_vli tbase = 0; |
| 536 size_t n; |
| 537 for (n = 1; n < start; ++n) { |
| 538 ubase += n * 4; |
| 539 tbase += n * 4 + 8; |
| 540 } |
| 541 |
| 542 while (n < start + 2 * radius) { |
| 543 expect(!lzma_index_iter_locate(&r, ubase + n * 4)); |
| 544 |
| 545 expect(r.block.compressed_file_offset == tbase + n * 4 + 8 |
| 546 + LZMA_STREAM_HEADER_SIZE); |
| 547 expect(r.block.uncompressed_file_offset == ubase + n * 4); |
| 548 |
| 549 tbase += n * 4 + 8; |
| 550 ubase += n * 4; |
| 551 ++n; |
| 552 |
| 553 expect(r.block.total_size == n * 4 + 8); |
| 554 expect(r.block.uncompressed_size == n * 4); |
| 555 } |
| 556 |
| 557 // Do it also backwards. |
| 558 while (n > start) { |
| 559 expect(!lzma_index_iter_locate(&r, ubase + (n - 1) * 4)); |
| 560 |
| 561 expect(r.block.total_size == n * 4 + 8); |
| 562 expect(r.block.uncompressed_size == n * 4); |
| 563 |
| 564 --n; |
| 565 tbase -= n * 4 + 8; |
| 566 ubase -= n * 4; |
| 567 |
| 568 expect(r.block.compressed_file_offset == tbase + n * 4 + 8 |
| 569 + LZMA_STREAM_HEADER_SIZE); |
| 570 expect(r.block.uncompressed_file_offset == ubase + n * 4); |
| 571 } |
| 572 |
| 573 // Test locating in concatenated Index. |
| 574 lzma_index_end(i, NULL); |
| 575 i = lzma_index_init(NULL); |
| 576 expect(i != NULL); |
| 577 lzma_index_iter_init(&r, i); |
| 578 for (n = 0; n < group_multiple; ++n) |
| 579 expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK); |
| 580 expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK); |
| 581 expect(!lzma_index_iter_locate(&r, 0)); |
| 582 expect(r.block.total_size == 16); |
| 583 expect(r.block.uncompressed_size == 1); |
| 584 expect(r.block.compressed_file_offset |
| 585 == LZMA_STREAM_HEADER_SIZE + group_multiple * 8); |
| 586 expect(r.block.uncompressed_file_offset == 0); |
| 587 |
| 588 lzma_index_end(i, NULL); |
| 589 } |
| 590 |
| 591 |
| 592 static void |
| 593 test_corrupt(void) |
| 594 { |
| 595 const size_t alloc_size = 128 * 1024; |
| 596 uint8_t *buf = malloc(alloc_size); |
| 597 expect(buf != NULL); |
| 598 lzma_stream strm = LZMA_STREAM_INIT; |
| 599 |
| 600 lzma_index *i = create_empty(); |
| 601 expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR); |
| 602 lzma_index_end(i, NULL); |
| 603 |
| 604 // Create a valid Index and corrupt it in different ways. |
| 605 i = create_small(); |
| 606 expect(lzma_index_encoder(&strm, i) == LZMA_OK); |
| 607 succeed(coder_loop(&strm, NULL, 0, buf, 20, |
| 608 LZMA_STREAM_END, LZMA_RUN)); |
| 609 lzma_index_end(i, NULL); |
| 610 |
| 611 // Wrong Index Indicator |
| 612 buf[0] ^= 1; |
| 613 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK); |
| 614 succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR)); |
| 615 buf[0] ^= 1; |
| 616 |
| 617 // Wrong Number of Records and thus CRC32 fails. |
| 618 --buf[1]; |
| 619 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK); |
| 620 succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR)); |
| 621 ++buf[1]; |
| 622 |
| 623 // Padding not NULs |
| 624 buf[15] ^= 1; |
| 625 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK); |
| 626 succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR)); |
| 627 |
| 628 lzma_end(&strm); |
| 629 free(buf); |
| 630 } |
| 631 |
| 632 |
| 633 int |
| 634 main(void) |
| 635 { |
| 636 test_equal(); |
| 637 |
| 638 test_overflow(); |
| 639 |
| 640 lzma_index *i = create_empty(); |
| 641 test_many(i); |
| 642 lzma_index_end(i, NULL); |
| 643 |
| 644 i = create_small(); |
| 645 test_many(i); |
| 646 lzma_index_end(i, NULL); |
| 647 |
| 648 i = create_big(); |
| 649 test_many(i); |
| 650 lzma_index_end(i, NULL); |
| 651 |
| 652 test_cat(); |
| 653 |
| 654 test_locate(); |
| 655 |
| 656 test_corrupt(); |
| 657 |
| 658 return 0; |
| 659 } |
OLD | NEW |