OLD | NEW |
(Empty) | |
| 1 /////////////////////////////////////////////////////////////////////////////// |
| 2 // |
| 3 /// \file stream_flags_decoder.c |
| 4 /// \brief Decodes Stream Header and Stream Footer from .xz files |
| 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 "stream_flags_common.h" |
| 14 |
| 15 |
| 16 static bool |
| 17 stream_flags_decode(lzma_stream_flags *options, const uint8_t *in) |
| 18 { |
| 19 // Reserved bits must be unset. |
| 20 if (in[0] != 0x00 || (in[1] & 0xF0)) |
| 21 return true; |
| 22 |
| 23 options->version = 0; |
| 24 options->check = in[1] & 0x0F; |
| 25 |
| 26 return false; |
| 27 } |
| 28 |
| 29 |
| 30 extern LZMA_API(lzma_ret) |
| 31 lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in) |
| 32 { |
| 33 // Magic |
| 34 if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0) |
| 35 return LZMA_FORMAT_ERROR; |
| 36 |
| 37 // Verify the CRC32 so we can distinguish between corrupt |
| 38 // and unsupported files. |
| 39 const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic), |
| 40 LZMA_STREAM_FLAGS_SIZE, 0); |
| 41 if (crc != unaligned_read32le(in + sizeof(lzma_header_magic) |
| 42 + LZMA_STREAM_FLAGS_SIZE)) |
| 43 return LZMA_DATA_ERROR; |
| 44 |
| 45 // Stream Flags |
| 46 if (stream_flags_decode(options, in + sizeof(lzma_header_magic))) |
| 47 return LZMA_OPTIONS_ERROR; |
| 48 |
| 49 // Set Backward Size to indicate unknown value. That way |
| 50 // lzma_stream_flags_compare() can be used to compare Stream Header |
| 51 // and Stream Footer while keeping it useful also for comparing |
| 52 // two Stream Footers. |
| 53 options->backward_size = LZMA_VLI_UNKNOWN; |
| 54 |
| 55 return LZMA_OK; |
| 56 } |
| 57 |
| 58 |
| 59 extern LZMA_API(lzma_ret) |
| 60 lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in) |
| 61 { |
| 62 // Magic |
| 63 if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE, |
| 64 lzma_footer_magic, sizeof(lzma_footer_magic)) != 0) |
| 65 return LZMA_FORMAT_ERROR; |
| 66 |
| 67 // CRC32 |
| 68 const uint32_t crc = lzma_crc32(in + sizeof(uint32_t), |
| 69 sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0); |
| 70 if (crc != unaligned_read32le(in)) |
| 71 return LZMA_DATA_ERROR; |
| 72 |
| 73 // Stream Flags |
| 74 if (stream_flags_decode(options, in + sizeof(uint32_t) * 2)) |
| 75 return LZMA_OPTIONS_ERROR; |
| 76 |
| 77 // Backward Size |
| 78 options->backward_size = unaligned_read32le(in + sizeof(uint32_t)); |
| 79 options->backward_size = (options->backward_size + 1) * 4; |
| 80 |
| 81 return LZMA_OK; |
| 82 } |
OLD | NEW |