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