/src/xz/src/liblzma/common/stream_flags_decoder.c
Line | Count | Source |
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 | 3.42k | { |
18 | | // Reserved bits must be unset. |
19 | 3.42k | if (in[0] != 0x00 || (in[1] & 0xF0)) |
20 | 23 | return true; |
21 | | |
22 | 3.40k | options->version = 0; |
23 | 3.40k | options->check = in[1] & 0x0F; |
24 | | |
25 | 3.40k | return false; |
26 | 3.42k | } |
27 | | |
28 | | |
29 | | extern LZMA_API(lzma_ret) |
30 | | lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in) |
31 | 3.04k | { |
32 | | // Magic |
33 | 3.04k | if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0) |
34 | 34 | return LZMA_FORMAT_ERROR; |
35 | | |
36 | | // Verify the CRC32 so we can distinguish between corrupt |
37 | | // and unsupported files. |
38 | 3.00k | const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic), |
39 | 3.00k | LZMA_STREAM_FLAGS_SIZE, 0); |
40 | 3.00k | if (crc != read32le(in + sizeof(lzma_header_magic) |
41 | 3.00k | + LZMA_STREAM_FLAGS_SIZE)) { |
42 | | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
43 | | return LZMA_DATA_ERROR; |
44 | | #endif |
45 | 1.78k | } |
46 | | |
47 | | // Stream Flags |
48 | 3.00k | if (stream_flags_decode(options, in + sizeof(lzma_header_magic))) |
49 | 4 | 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 | 3.00k | options->backward_size = LZMA_VLI_UNKNOWN; |
56 | | |
57 | 3.00k | return LZMA_OK; |
58 | 3.00k | } |
59 | | |
60 | | |
61 | | extern LZMA_API(lzma_ret) |
62 | | lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in) |
63 | 426 | { |
64 | | // Magic |
65 | 426 | if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE, |
66 | 426 | lzma_footer_magic, sizeof(lzma_footer_magic)) != 0) |
67 | 11 | return LZMA_FORMAT_ERROR; |
68 | | |
69 | | // CRC32 |
70 | 415 | const uint32_t crc = lzma_crc32(in + sizeof(uint32_t), |
71 | 415 | sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0); |
72 | 415 | if (crc != read32le(in)) { |
73 | | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
74 | | return LZMA_DATA_ERROR; |
75 | | #endif |
76 | 42 | } |
77 | | |
78 | | // Stream Flags |
79 | 415 | if (stream_flags_decode(options, in + sizeof(uint32_t) * 2)) |
80 | 19 | return LZMA_OPTIONS_ERROR; |
81 | | |
82 | | // Backward Size |
83 | 396 | options->backward_size = read32le(in + sizeof(uint32_t)); |
84 | 396 | options->backward_size = (options->backward_size + 1) * 4; |
85 | | |
86 | 396 | return LZMA_OK; |
87 | 415 | } |