stream_flags_decoder.c 2.3 KB

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