11592Srgrimes/////////////////////////////////////////////////////////////////////////////// 21592Srgrimes// 31592Srgrimes/// \file stream_flags_decoder.c 41592Srgrimes/// \brief Decodes Stream Header and Stream Footer from .xz files 51592Srgrimes// 61592Srgrimes// Author: Lasse Collin 71592Srgrimes// 81592Srgrimes// This file has been put into the public domain. 91592Srgrimes// You can do whatever you want with this file. 101592Srgrimes// 111592Srgrimes/////////////////////////////////////////////////////////////////////////////// 121592Srgrimes 131592Srgrimes#include "stream_flags_common.h" 141592Srgrimes 151592Srgrimes 161592Srgrimesstatic bool 171592Srgrimesstream_flags_decode(lzma_stream_flags *options, const uint8_t *in) 181592Srgrimes{ 191592Srgrimes // Reserved bits must be unset. 201592Srgrimes if (in[0] != 0x00 || (in[1] & 0xF0)) 211592Srgrimes return true; 221592Srgrimes 231592Srgrimes options->version = 0; 241592Srgrimes options->check = in[1] & 0x0F; 251592Srgrimes 261592Srgrimes return false; 271592Srgrimes} 281592Srgrimes 291592Srgrimes 301592Srgrimesextern LZMA_API(lzma_ret) 311592Srgrimeslzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in) 321592Srgrimes{ 331592Srgrimes // Magic 341592Srgrimes if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0) 3531512Scharnier return LZMA_FORMAT_ERROR; 361592Srgrimes 371592Srgrimes // Verify the CRC32 so we can distinguish between corrupt 381592Srgrimes // and unsupported files. 391592Srgrimes const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic), 401592Srgrimes LZMA_STREAM_FLAGS_SIZE, 0); 4131512Scharnier if (crc != unaligned_read32le(in + sizeof(lzma_header_magic) 421592Srgrimes + LZMA_STREAM_FLAGS_SIZE)) 4331512Scharnier return LZMA_DATA_ERROR; 4431512Scharnier 4550476Speter // Stream Flags 461592Srgrimes if (stream_flags_decode(options, in + sizeof(lzma_header_magic))) 471592Srgrimes return LZMA_OPTIONS_ERROR; 481592Srgrimes 491592Srgrimes // Set Backward Size to indicate unknown value. That way 501592Srgrimes // lzma_stream_flags_compare() can be used to compare Stream Header 511592Srgrimes // and Stream Footer while keeping it useful also for comparing 521592Srgrimes // two Stream Footers. 531592Srgrimes options->backward_size = LZMA_VLI_UNKNOWN; 541592Srgrimes 551592Srgrimes return LZMA_OK; 561592Srgrimes} 571592Srgrimes 581592Srgrimes 5918458Simpextern LZMA_API(lzma_ret) 601592Srgrimeslzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in) 611592Srgrimes{ 621592Srgrimes // Magic 631592Srgrimes if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE, 641592Srgrimes lzma_footer_magic, sizeof(lzma_footer_magic)) != 0) 651592Srgrimes return LZMA_FORMAT_ERROR; 661592Srgrimes 671592Srgrimes // CRC32 6845393Sbrian const uint32_t crc = lzma_crc32(in + sizeof(uint32_t), 691592Srgrimes sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0); 7031512Scharnier if (crc != unaligned_read32le(in)) 711592Srgrimes return LZMA_DATA_ERROR; 721592Srgrimes 731592Srgrimes // Stream Flags 741592Srgrimes if (stream_flags_decode(options, in + sizeof(uint32_t) * 2)) 751592Srgrimes return LZMA_OPTIONS_ERROR; 761592Srgrimes 771592Srgrimes // Backward Size 781592Srgrimes options->backward_size = unaligned_read32le(in + sizeof(uint32_t)); 791592Srgrimes options->backward_size = (options->backward_size + 1) * 4; 801592Srgrimes 811592Srgrimes return LZMA_OK; 8284047Sobrien} 831592Srgrimes