block_util.c 2.6 KB

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