(root)/
xz-5.4.5/
src/
liblzma/
common/
block_util.c
       1  ///////////////////////////////////////////////////////////////////////////////
       2  //
       3  /// \file       block_util.c
       4  /// \brief      Utility functions to handle lzma_block
       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 "common.h"
      14  #include "index.h"
      15  
      16  
      17  extern LZMA_API(lzma_ret)
      18  lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size)
      19  {
      20  	// Validate everything but Uncompressed Size and filters.
      21  	if (lzma_block_unpadded_size(block) == 0)
      22  		return LZMA_PROG_ERROR;
      23  
      24  	const uint32_t container_size = block->header_size
      25  			+ lzma_check_size(block->check);
      26  
      27  	// Validate that Compressed Size will be greater than zero.
      28  	if (unpadded_size <= container_size)
      29  		return LZMA_DATA_ERROR;
      30  
      31  	// Calculate what Compressed Size is supposed to be.
      32  	// If Compressed Size was present in Block Header,
      33  	// compare that the new value matches it.
      34  	const lzma_vli compressed_size = unpadded_size - container_size;
      35  	if (block->compressed_size != LZMA_VLI_UNKNOWN
      36  			&& block->compressed_size != compressed_size)
      37  		return LZMA_DATA_ERROR;
      38  
      39  	block->compressed_size = compressed_size;
      40  
      41  	return LZMA_OK;
      42  }
      43  
      44  
      45  extern LZMA_API(lzma_vli)
      46  lzma_block_unpadded_size(const lzma_block *block)
      47  {
      48  	// Validate the values that we are interested in i.e. all but
      49  	// Uncompressed Size and the filters.
      50  	//
      51  	// NOTE: This function is used for validation too, so it is
      52  	// essential that these checks are always done even if
      53  	// Compressed Size is unknown.
      54  	if (block == NULL || block->version > 1
      55  			|| block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
      56  			|| block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
      57  			|| (block->header_size & 3)
      58  			|| !lzma_vli_is_valid(block->compressed_size)
      59  			|| block->compressed_size == 0
      60  			|| (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
      61  		return 0;
      62  
      63  	// If Compressed Size is unknown, return that we cannot know
      64  	// size of the Block either.
      65  	if (block->compressed_size == LZMA_VLI_UNKNOWN)
      66  		return LZMA_VLI_UNKNOWN;
      67  
      68  	// Calculate Unpadded Size and validate it.
      69  	const lzma_vli unpadded_size = block->compressed_size
      70  				+ block->header_size
      71  				+ lzma_check_size(block->check);
      72  
      73  	assert(unpadded_size >= UNPADDED_SIZE_MIN);
      74  	if (unpadded_size > UNPADDED_SIZE_MAX)
      75  		return 0;
      76  
      77  	return unpadded_size;
      78  }
      79  
      80  
      81  extern LZMA_API(lzma_vli)
      82  lzma_block_total_size(const lzma_block *block)
      83  {
      84  	lzma_vli unpadded_size = lzma_block_unpadded_size(block);
      85  
      86  	if (unpadded_size != LZMA_VLI_UNKNOWN)
      87  		unpadded_size = vli_ceil4(unpadded_size);
      88  
      89  	return unpadded_size;
      90  }