block_util.c 2.5 KB

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