1 // SPDX-License-Identifier: 0BSD
3 ///////////////////////////////////////////////////////////////////////////////
5 /// \file stream_flags_decoder.c
6 /// \brief Decodes Stream Header and Stream Footer from .xz files
8 // Author: Lasse Collin
10 ///////////////////////////////////////////////////////////////////////////////
12 #include "stream_flags_common.h"
16 stream_flags_decode(lzma_stream_flags
*options
, const uint8_t *in
)
18 // Reserved bits must be unset.
19 if (in
[0] != 0x00 || (in
[1] & 0xF0))
23 options
->check
= in
[1] & 0x0F;
29 extern LZMA_API(lzma_ret
)
30 lzma_stream_header_decode(lzma_stream_flags
*options
, const uint8_t *in
)
33 if (memcmp(in
, lzma_header_magic
, sizeof(lzma_header_magic
)) != 0)
34 return LZMA_FORMAT_ERROR
;
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
;
48 if (stream_flags_decode(options
, in
+ sizeof(lzma_header_magic
)))
49 return LZMA_OPTIONS_ERROR
;
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
;
61 extern LZMA_API(lzma_ret
)
62 lzma_stream_footer_decode(lzma_stream_flags
*options
, const uint8_t *in
)
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
;
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
;
79 if (stream_flags_decode(options
, in
+ sizeof(uint32_t) * 2))
80 return LZMA_OPTIONS_ERROR
;
83 options
->backward_size
= read32le(in
+ sizeof(uint32_t));
84 options
->backward_size
= (options
->backward_size
+ 1) * 4;