(root)/
xz-5.4.5/
src/
liblzma/
common/
stream_flags_decoder.c
       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  }