stream_flags_decoder.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // SPDX-License-Identifier: 0BSD
  2. ///////////////////////////////////////////////////////////////////////////////
  3. //
  4. /// \file stream_flags_decoder.c
  5. /// \brief Decodes Stream Header and Stream Footer from .xz files
  6. //
  7. // Author: Lasse Collin
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include "stream_flags_common.h"
  11. static bool
  12. stream_flags_decode(lzma_stream_flags *options, const uint8_t *in)
  13. {
  14. // Reserved bits must be unset.
  15. if (in[0] != 0x00 || (in[1] & 0xF0))
  16. return true;
  17. options->version = 0;
  18. options->check = in[1] & 0x0F;
  19. return false;
  20. }
  21. extern LZMA_API(lzma_ret)
  22. lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in)
  23. {
  24. // Magic
  25. if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0)
  26. return LZMA_FORMAT_ERROR;
  27. // Verify the CRC32 so we can distinguish between corrupt
  28. // and unsupported files.
  29. const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic),
  30. LZMA_STREAM_FLAGS_SIZE, 0);
  31. if (crc != read32le(in + sizeof(lzma_header_magic)
  32. + LZMA_STREAM_FLAGS_SIZE)) {
  33. #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  34. return LZMA_DATA_ERROR;
  35. #endif
  36. }
  37. // Stream Flags
  38. if (stream_flags_decode(options, in + sizeof(lzma_header_magic)))
  39. return LZMA_OPTIONS_ERROR;
  40. // Set Backward Size to indicate unknown value. That way
  41. // lzma_stream_flags_compare() can be used to compare Stream Header
  42. // and Stream Footer while keeping it useful also for comparing
  43. // two Stream Footers.
  44. options->backward_size = LZMA_VLI_UNKNOWN;
  45. return LZMA_OK;
  46. }
  47. extern LZMA_API(lzma_ret)
  48. lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in)
  49. {
  50. // Magic
  51. if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE,
  52. lzma_footer_magic, sizeof(lzma_footer_magic)) != 0)
  53. return LZMA_FORMAT_ERROR;
  54. // CRC32
  55. const uint32_t crc = lzma_crc32(in + sizeof(uint32_t),
  56. sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0);
  57. if (crc != read32le(in)) {
  58. #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  59. return LZMA_DATA_ERROR;
  60. #endif
  61. }
  62. // Stream Flags
  63. if (stream_flags_decode(options, in + sizeof(uint32_t) * 2))
  64. return LZMA_OPTIONS_ERROR;
  65. // Backward Size
  66. options->backward_size = read32le(in + sizeof(uint32_t));
  67. options->backward_size = (options->backward_size + 1) * 4;
  68. return LZMA_OK;
  69. }