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