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 != read32le(in + sizeof(lzma_header_magic)
|
---|
42 | + LZMA_STREAM_FLAGS_SIZE)) {
|
---|
43 | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
---|
44 | return LZMA_DATA_ERROR;
|
---|
45 | #endif
|
---|
46 | }
|
---|
47 |
|
---|
48 | // Stream Flags
|
---|
49 | if (stream_flags_decode(options, in + sizeof(lzma_header_magic)))
|
---|
50 | return LZMA_OPTIONS_ERROR;
|
---|
51 |
|
---|
52 | // Set Backward Size to indicate unknown value. That way
|
---|
53 | // lzma_stream_flags_compare() can be used to compare Stream Header
|
---|
54 | // and Stream Footer while keeping it useful also for comparing
|
---|
55 | // two Stream Footers.
|
---|
56 | options->backward_size = LZMA_VLI_UNKNOWN;
|
---|
57 |
|
---|
58 | return LZMA_OK;
|
---|
59 | }
|
---|
60 |
|
---|
61 |
|
---|
62 | extern LZMA_API(lzma_ret)
|
---|
63 | lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in)
|
---|
64 | {
|
---|
65 | // Magic
|
---|
66 | if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE,
|
---|
67 | lzma_footer_magic, sizeof(lzma_footer_magic)) != 0)
|
---|
68 | return LZMA_FORMAT_ERROR;
|
---|
69 |
|
---|
70 | // CRC32
|
---|
71 | const uint32_t crc = lzma_crc32(in + sizeof(uint32_t),
|
---|
72 | sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0);
|
---|
73 | if (crc != read32le(in)) {
|
---|
74 | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
---|
75 | return LZMA_DATA_ERROR;
|
---|
76 | #endif
|
---|
77 | }
|
---|
78 |
|
---|
79 | // Stream Flags
|
---|
80 | if (stream_flags_decode(options, in + sizeof(uint32_t) * 2))
|
---|
81 | return LZMA_OPTIONS_ERROR;
|
---|
82 |
|
---|
83 | // Backward Size
|
---|
84 | options->backward_size = read32le(in + sizeof(uint32_t));
|
---|
85 | options->backward_size = (options->backward_size + 1) * 4;
|
---|
86 |
|
---|
87 | return LZMA_OK;
|
---|
88 | }
|
---|