OLD | NEW |
1 /////////////////////////////////////////////////////////////////////////////// | 1 /////////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 /// \file list.c | 3 /// \file list.c |
4 /// \brief Listing information about .xz files | 4 /// \brief Listing information about .xz files |
5 // | 5 // |
6 // Author: Lasse Collin | 6 // Author: Lasse Collin |
7 // | 7 // |
8 // This file has been put into the public domain. | 8 // This file has been put into the public domain. |
9 // You can do whatever you want with this file. | 9 // You can do whatever you want with this file. |
10 // | 10 // |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 } | 196 } |
197 | 197 |
198 // Decode the Stream Footer. | 198 // Decode the Stream Footer. |
199 ret = lzma_stream_footer_decode(&footer_flags, buf.u8); | 199 ret = lzma_stream_footer_decode(&footer_flags, buf.u8); |
200 if (ret != LZMA_OK) { | 200 if (ret != LZMA_OK) { |
201 message_error("%s: %s", pair->src_name, | 201 message_error("%s: %s", pair->src_name, |
202 message_strm(ret)); | 202 message_strm(ret)); |
203 goto error; | 203 goto error; |
204 } | 204 } |
205 | 205 |
| 206 // Check that the Stream Footer doesn't specify something |
| 207 // that we don't support. This can only happen if the xz |
| 208 // version is older than liblzma and liblzma supports |
| 209 // something new. |
| 210 // |
| 211 // It is enough to check Stream Footer. Stream Header must |
| 212 // match when it is compared against Stream Footer with |
| 213 // lzma_stream_flags_compare(). |
| 214 if (footer_flags.version != 0) { |
| 215 message_error("%s: %s", pair->src_name, |
| 216 message_strm(LZMA_OPTIONS_ERROR)); |
| 217 goto error; |
| 218 } |
| 219 |
206 // Check that the size of the Index field looks sane. | 220 // Check that the size of the Index field looks sane. |
207 lzma_vli index_size = footer_flags.backward_size; | 221 lzma_vli index_size = footer_flags.backward_size; |
208 if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) { | 222 if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) { |
209 message_error("%s: %s", pair->src_name, | 223 message_error("%s: %s", pair->src_name, |
210 message_strm(LZMA_DATA_ERROR)); | 224 message_strm(LZMA_DATA_ERROR)); |
211 goto error; | 225 goto error; |
212 } | 226 } |
213 | 227 |
214 // Set pos to the beginning of the Index. | 228 // Set pos to the beginning of the Index. |
215 pos -= index_size; | 229 pos -= index_size; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 // Collect information if all Blocks have both Compressed Size | 436 // Collect information if all Blocks have both Compressed Size |
423 // and Uncompressed Size fields. They can be useful e.g. for | 437 // and Uncompressed Size fields. They can be useful e.g. for |
424 // multi-threaded decompression so it can be useful to know it. | 438 // multi-threaded decompression so it can be useful to know it. |
425 xfi->all_have_sizes &= block.compressed_size != LZMA_VLI_UNKNOWN | 439 xfi->all_have_sizes &= block.compressed_size != LZMA_VLI_UNKNOWN |
426 && block.uncompressed_size != LZMA_VLI_UNKNOWN; | 440 && block.uncompressed_size != LZMA_VLI_UNKNOWN; |
427 | 441 |
428 // Validate or set block.compressed_size. | 442 // Validate or set block.compressed_size. |
429 switch (lzma_block_compressed_size(&block, | 443 switch (lzma_block_compressed_size(&block, |
430 iter->block.unpadded_size)) { | 444 iter->block.unpadded_size)) { |
431 case LZMA_OK: | 445 case LZMA_OK: |
432 » » break; | 446 » » // Validate also block.uncompressed_size if it is present. |
| 447 » » // If it isn't present, there's no need to set it since |
| 448 » » // we aren't going to actually decompress the Block; if |
| 449 » » // we were decompressing, then we should set it so that |
| 450 » » // the Block decoder could validate the Uncompressed Size |
| 451 » » // that was stored in the Index. |
| 452 » » if (block.uncompressed_size == LZMA_VLI_UNKNOWN |
| 453 » » » » || block.uncompressed_size |
| 454 » » » » » == iter->block.uncompressed_size) |
| 455 » » » break; |
| 456 |
| 457 » » // If the above fails, the file is corrupt so |
| 458 » » // LZMA_DATA_ERROR is a good error code. |
433 | 459 |
434 case LZMA_DATA_ERROR: | 460 case LZMA_DATA_ERROR: |
435 // Free the memory allocated by lzma_block_header_decode(). | 461 // Free the memory allocated by lzma_block_header_decode(). |
436 for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) | 462 for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) |
437 free(filters[i].options); | 463 free(filters[i].options); |
438 | 464 |
439 goto data_error; | 465 goto data_error; |
440 | 466 |
441 default: | 467 default: |
442 message_bug(); | 468 message_bug(); |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 // broken files. | 1126 // broken files. |
1101 if (!fail) | 1127 if (!fail) |
1102 update_totals(&xfi); | 1128 update_totals(&xfi); |
1103 | 1129 |
1104 lzma_index_end(xfi.idx, NULL); | 1130 lzma_index_end(xfi.idx, NULL); |
1105 } | 1131 } |
1106 | 1132 |
1107 io_close(pair, false); | 1133 io_close(pair, false); |
1108 return; | 1134 return; |
1109 } | 1135 } |
OLD | NEW |