(root)/
xz-5.4.5/
src/
liblzma/
common/
stream_decoder.c
       1  ///////////////////////////////////////////////////////////////////////////////
       2  //
       3  /// \file       stream_decoder.c
       4  /// \brief      Decodes .xz Streams
       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  
      13  #include "stream_decoder.h"
      14  #include "block_decoder.h"
      15  #include "index.h"
      16  
      17  
      18  typedef struct {
      19  	enum {
      20  		SEQ_STREAM_HEADER,
      21  		SEQ_BLOCK_HEADER,
      22  		SEQ_BLOCK_INIT,
      23  		SEQ_BLOCK_RUN,
      24  		SEQ_INDEX,
      25  		SEQ_STREAM_FOOTER,
      26  		SEQ_STREAM_PADDING,
      27  	} sequence;
      28  
      29  	/// Block decoder
      30  	lzma_next_coder block_decoder;
      31  
      32  	/// Block options decoded by the Block Header decoder and used by
      33  	/// the Block decoder.
      34  	lzma_block block_options;
      35  
      36  	/// Stream Flags from Stream Header
      37  	lzma_stream_flags stream_flags;
      38  
      39  	/// Index is hashed so that it can be compared to the sizes of Blocks
      40  	/// with O(1) memory usage.
      41  	lzma_index_hash *index_hash;
      42  
      43  	/// Memory usage limit
      44  	uint64_t memlimit;
      45  
      46  	/// Amount of memory actually needed (only an estimate)
      47  	uint64_t memusage;
      48  
      49  	/// If true, LZMA_NO_CHECK is returned if the Stream has
      50  	/// no integrity check.
      51  	bool tell_no_check;
      52  
      53  	/// If true, LZMA_UNSUPPORTED_CHECK is returned if the Stream has
      54  	/// an integrity check that isn't supported by this liblzma build.
      55  	bool tell_unsupported_check;
      56  
      57  	/// If true, LZMA_GET_CHECK is returned after decoding Stream Header.
      58  	bool tell_any_check;
      59  
      60  	/// If true, we will tell the Block decoder to skip calculating
      61  	/// and verifying the integrity check.
      62  	bool ignore_check;
      63  
      64  	/// If true, we will decode concatenated Streams that possibly have
      65  	/// Stream Padding between or after them. LZMA_STREAM_END is returned
      66  	/// once the application isn't giving us any new input (LZMA_FINISH),
      67  	/// and we aren't in the middle of a Stream, and possible
      68  	/// Stream Padding is a multiple of four bytes.
      69  	bool concatenated;
      70  
      71  	/// When decoding concatenated Streams, this is true as long as we
      72  	/// are decoding the first Stream. This is needed to avoid misleading
      73  	/// LZMA_FORMAT_ERROR in case the later Streams don't have valid magic
      74  	/// bytes.
      75  	bool first_stream;
      76  
      77  	/// Write position in buffer[] and position in Stream Padding
      78  	size_t pos;
      79  
      80  	/// Buffer to hold Stream Header, Block Header, and Stream Footer.
      81  	/// Block Header has biggest maximum size.
      82  	uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];
      83  } lzma_stream_coder;
      84  
      85  
      86  static lzma_ret
      87  stream_decoder_reset(lzma_stream_coder *coder, const lzma_allocator *allocator)
      88  {
      89  	// Initialize the Index hash used to verify the Index.
      90  	coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator);
      91  	if (coder->index_hash == NULL)
      92  		return LZMA_MEM_ERROR;
      93  
      94  	// Reset the rest of the variables.
      95  	coder->sequence = SEQ_STREAM_HEADER;
      96  	coder->pos = 0;
      97  
      98  	return LZMA_OK;
      99  }
     100  
     101  
     102  static lzma_ret
     103  stream_decode(void *coder_ptr, const lzma_allocator *allocator,
     104  		const uint8_t *restrict in, size_t *restrict in_pos,
     105  		size_t in_size, uint8_t *restrict out,
     106  		size_t *restrict out_pos, size_t out_size, lzma_action action)
     107  {
     108  	lzma_stream_coder *coder = coder_ptr;
     109  
     110  	// When decoding the actual Block, it may be able to produce more
     111  	// output even if we don't give it any new input.
     112  	while (true)
     113  	switch (coder->sequence) {
     114  	case SEQ_STREAM_HEADER: {
     115  		// Copy the Stream Header to the internal buffer.
     116  		lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,
     117  				LZMA_STREAM_HEADER_SIZE);
     118  
     119  		// Return if we didn't get the whole Stream Header yet.
     120  		if (coder->pos < LZMA_STREAM_HEADER_SIZE)
     121  			return LZMA_OK;
     122  
     123  		coder->pos = 0;
     124  
     125  		// Decode the Stream Header.
     126  		const lzma_ret ret = lzma_stream_header_decode(
     127  				&coder->stream_flags, coder->buffer);
     128  		if (ret != LZMA_OK)
     129  			return ret == LZMA_FORMAT_ERROR && !coder->first_stream
     130  					? LZMA_DATA_ERROR : ret;
     131  
     132  		// If we are decoding concatenated Streams, and the later
     133  		// Streams have invalid Header Magic Bytes, we give
     134  		// LZMA_DATA_ERROR instead of LZMA_FORMAT_ERROR.
     135  		coder->first_stream = false;
     136  
     137  		// Copy the type of the Check so that Block Header and Block
     138  		// decoders see it.
     139  		coder->block_options.check = coder->stream_flags.check;
     140  
     141  		// Even if we return LZMA_*_CHECK below, we want
     142  		// to continue from Block Header decoding.
     143  		coder->sequence = SEQ_BLOCK_HEADER;
     144  
     145  		// Detect if there's no integrity check or if it is
     146  		// unsupported if those were requested by the application.
     147  		if (coder->tell_no_check && coder->stream_flags.check
     148  				== LZMA_CHECK_NONE)
     149  			return LZMA_NO_CHECK;
     150  
     151  		if (coder->tell_unsupported_check
     152  				&& !lzma_check_is_supported(
     153  					coder->stream_flags.check))
     154  			return LZMA_UNSUPPORTED_CHECK;
     155  
     156  		if (coder->tell_any_check)
     157  			return LZMA_GET_CHECK;
     158  	}
     159  
     160  	// Fall through
     161  
     162  	case SEQ_BLOCK_HEADER: {
     163  		if (*in_pos >= in_size)
     164  			return LZMA_OK;
     165  
     166  		if (coder->pos == 0) {
     167  			// Detect if it's Index.
     168  			if (in[*in_pos] == INDEX_INDICATOR) {
     169  				coder->sequence = SEQ_INDEX;
     170  				break;
     171  			}
     172  
     173  			// Calculate the size of the Block Header. Note that
     174  			// Block Header decoder wants to see this byte too
     175  			// so don't advance *in_pos.
     176  			coder->block_options.header_size
     177  					= lzma_block_header_size_decode(
     178  						in[*in_pos]);
     179  		}
     180  
     181  		// Copy the Block Header to the internal buffer.
     182  		lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,
     183  				coder->block_options.header_size);
     184  
     185  		// Return if we didn't get the whole Block Header yet.
     186  		if (coder->pos < coder->block_options.header_size)
     187  			return LZMA_OK;
     188  
     189  		coder->pos = 0;
     190  		coder->sequence = SEQ_BLOCK_INIT;
     191  	}
     192  
     193  	// Fall through
     194  
     195  	case SEQ_BLOCK_INIT: {
     196  		// Checking memusage and doing the initialization needs
     197  		// its own sequence point because we need to be able to
     198  		// retry if we return LZMA_MEMLIMIT_ERROR.
     199  
     200  		// Version 1 is needed to support the .ignore_check option.
     201  		coder->block_options.version = 1;
     202  
     203  		// Set up a buffer to hold the filter chain. Block Header
     204  		// decoder will initialize all members of this array so
     205  		// we don't need to do it here.
     206  		lzma_filter filters[LZMA_FILTERS_MAX + 1];
     207  		coder->block_options.filters = filters;
     208  
     209  		// Decode the Block Header.
     210  		return_if_error(lzma_block_header_decode(&coder->block_options,
     211  				allocator, coder->buffer));
     212  
     213  		// If LZMA_IGNORE_CHECK was used, this flag needs to be set.
     214  		// It has to be set after lzma_block_header_decode() because
     215  		// it always resets this to false.
     216  		coder->block_options.ignore_check = coder->ignore_check;
     217  
     218  		// Check the memory usage limit.
     219  		const uint64_t memusage = lzma_raw_decoder_memusage(filters);
     220  		lzma_ret ret;
     221  
     222  		if (memusage == UINT64_MAX) {
     223  			// One or more unknown Filter IDs.
     224  			ret = LZMA_OPTIONS_ERROR;
     225  		} else {
     226  			// Now we can set coder->memusage since we know that
     227  			// the filter chain is valid. We don't want
     228  			// lzma_memusage() to return UINT64_MAX in case of
     229  			// invalid filter chain.
     230  			coder->memusage = memusage;
     231  
     232  			if (memusage > coder->memlimit) {
     233  				// The chain would need too much memory.
     234  				ret = LZMA_MEMLIMIT_ERROR;
     235  			} else {
     236  				// Memory usage is OK.
     237  				// Initialize the Block decoder.
     238  				ret = lzma_block_decoder_init(
     239  						&coder->block_decoder,
     240  						allocator,
     241  						&coder->block_options);
     242  			}
     243  		}
     244  
     245  		// Free the allocated filter options since they are needed
     246  		// only to initialize the Block decoder.
     247  		lzma_filters_free(filters, allocator);
     248  		coder->block_options.filters = NULL;
     249  
     250  		// Check if memory usage calculation and Block decoder
     251  		// initialization succeeded.
     252  		if (ret != LZMA_OK)
     253  			return ret;
     254  
     255  		coder->sequence = SEQ_BLOCK_RUN;
     256  	}
     257  
     258  	// Fall through
     259  
     260  	case SEQ_BLOCK_RUN: {
     261  		const lzma_ret ret = coder->block_decoder.code(
     262  				coder->block_decoder.coder, allocator,
     263  				in, in_pos, in_size, out, out_pos, out_size,
     264  				action);
     265  
     266  		if (ret != LZMA_STREAM_END)
     267  			return ret;
     268  
     269  		// Block decoded successfully. Add the new size pair to
     270  		// the Index hash.
     271  		return_if_error(lzma_index_hash_append(coder->index_hash,
     272  				lzma_block_unpadded_size(
     273  					&coder->block_options),
     274  				coder->block_options.uncompressed_size));
     275  
     276  		coder->sequence = SEQ_BLOCK_HEADER;
     277  		break;
     278  	}
     279  
     280  	case SEQ_INDEX: {
     281  		// If we don't have any input, don't call
     282  		// lzma_index_hash_decode() since it would return
     283  		// LZMA_BUF_ERROR, which we must not do here.
     284  		if (*in_pos >= in_size)
     285  			return LZMA_OK;
     286  
     287  		// Decode the Index and compare it to the hash calculated
     288  		// from the sizes of the Blocks (if any).
     289  		const lzma_ret ret = lzma_index_hash_decode(coder->index_hash,
     290  				in, in_pos, in_size);
     291  		if (ret != LZMA_STREAM_END)
     292  			return ret;
     293  
     294  		coder->sequence = SEQ_STREAM_FOOTER;
     295  	}
     296  
     297  	// Fall through
     298  
     299  	case SEQ_STREAM_FOOTER: {
     300  		// Copy the Stream Footer to the internal buffer.
     301  		lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,
     302  				LZMA_STREAM_HEADER_SIZE);
     303  
     304  		// Return if we didn't get the whole Stream Footer yet.
     305  		if (coder->pos < LZMA_STREAM_HEADER_SIZE)
     306  			return LZMA_OK;
     307  
     308  		coder->pos = 0;
     309  
     310  		// Decode the Stream Footer. The decoder gives
     311  		// LZMA_FORMAT_ERROR if the magic bytes don't match,
     312  		// so convert that return code to LZMA_DATA_ERROR.
     313  		lzma_stream_flags footer_flags;
     314  		const lzma_ret ret = lzma_stream_footer_decode(
     315  				&footer_flags, coder->buffer);
     316  		if (ret != LZMA_OK)
     317  			return ret == LZMA_FORMAT_ERROR
     318  					? LZMA_DATA_ERROR : ret;
     319  
     320  		// Check that Index Size stored in the Stream Footer matches
     321  		// the real size of the Index field.
     322  		if (lzma_index_hash_size(coder->index_hash)
     323  				!= footer_flags.backward_size)
     324  			return LZMA_DATA_ERROR;
     325  
     326  		// Compare that the Stream Flags fields are identical in
     327  		// both Stream Header and Stream Footer.
     328  		return_if_error(lzma_stream_flags_compare(
     329  				&coder->stream_flags, &footer_flags));
     330  
     331  		if (!coder->concatenated)
     332  			return LZMA_STREAM_END;
     333  
     334  		coder->sequence = SEQ_STREAM_PADDING;
     335  	}
     336  
     337  	// Fall through
     338  
     339  	case SEQ_STREAM_PADDING:
     340  		assert(coder->concatenated);
     341  
     342  		// Skip over possible Stream Padding.
     343  		while (true) {
     344  			if (*in_pos >= in_size) {
     345  				// Unless LZMA_FINISH was used, we cannot
     346  				// know if there's more input coming later.
     347  				if (action != LZMA_FINISH)
     348  					return LZMA_OK;
     349  
     350  				// Stream Padding must be a multiple of
     351  				// four bytes.
     352  				return coder->pos == 0
     353  						? LZMA_STREAM_END
     354  						: LZMA_DATA_ERROR;
     355  			}
     356  
     357  			// If the byte is not zero, it probably indicates
     358  			// beginning of a new Stream (or the file is corrupt).
     359  			if (in[*in_pos] != 0x00)
     360  				break;
     361  
     362  			++*in_pos;
     363  			coder->pos = (coder->pos + 1) & 3;
     364  		}
     365  
     366  		// Stream Padding must be a multiple of four bytes (empty
     367  		// Stream Padding is OK).
     368  		if (coder->pos != 0) {
     369  			++*in_pos;
     370  			return LZMA_DATA_ERROR;
     371  		}
     372  
     373  		// Prepare to decode the next Stream.
     374  		return_if_error(stream_decoder_reset(coder, allocator));
     375  		break;
     376  
     377  	default:
     378  		assert(0);
     379  		return LZMA_PROG_ERROR;
     380  	}
     381  
     382  	// Never reached
     383  }
     384  
     385  
     386  static void
     387  stream_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
     388  {
     389  	lzma_stream_coder *coder = coder_ptr;
     390  	lzma_next_end(&coder->block_decoder, allocator);
     391  	lzma_index_hash_end(coder->index_hash, allocator);
     392  	lzma_free(coder, allocator);
     393  	return;
     394  }
     395  
     396  
     397  static lzma_check
     398  stream_decoder_get_check(const void *coder_ptr)
     399  {
     400  	const lzma_stream_coder *coder = coder_ptr;
     401  	return coder->stream_flags.check;
     402  }
     403  
     404  
     405  static lzma_ret
     406  stream_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
     407  		uint64_t *old_memlimit, uint64_t new_memlimit)
     408  {
     409  	lzma_stream_coder *coder = coder_ptr;
     410  
     411  	*memusage = coder->memusage;
     412  	*old_memlimit = coder->memlimit;
     413  
     414  	if (new_memlimit != 0) {
     415  		if (new_memlimit < coder->memusage)
     416  			return LZMA_MEMLIMIT_ERROR;
     417  
     418  		coder->memlimit = new_memlimit;
     419  	}
     420  
     421  	return LZMA_OK;
     422  }
     423  
     424  
     425  extern lzma_ret
     426  lzma_stream_decoder_init(
     427  		lzma_next_coder *next, const lzma_allocator *allocator,
     428  		uint64_t memlimit, uint32_t flags)
     429  {
     430  	lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);
     431  
     432  	if (flags & ~LZMA_SUPPORTED_FLAGS)
     433  		return LZMA_OPTIONS_ERROR;
     434  
     435  	lzma_stream_coder *coder = next->coder;
     436  	if (coder == NULL) {
     437  		coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);
     438  		if (coder == NULL)
     439  			return LZMA_MEM_ERROR;
     440  
     441  		next->coder = coder;
     442  		next->code = &stream_decode;
     443  		next->end = &stream_decoder_end;
     444  		next->get_check = &stream_decoder_get_check;
     445  		next->memconfig = &stream_decoder_memconfig;
     446  
     447  		coder->block_decoder = LZMA_NEXT_CODER_INIT;
     448  		coder->index_hash = NULL;
     449  	}
     450  
     451  	coder->memlimit = my_max(1, memlimit);
     452  	coder->memusage = LZMA_MEMUSAGE_BASE;
     453  	coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0;
     454  	coder->tell_unsupported_check
     455  			= (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0;
     456  	coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;
     457  	coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0;
     458  	coder->concatenated = (flags & LZMA_CONCATENATED) != 0;
     459  	coder->first_stream = true;
     460  
     461  	return stream_decoder_reset(coder, allocator);
     462  }
     463  
     464  
     465  extern LZMA_API(lzma_ret)
     466  lzma_stream_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags)
     467  {
     468  	lzma_next_strm_init(lzma_stream_decoder_init, strm, memlimit, flags);
     469  
     470  	strm->internal->supported_actions[LZMA_RUN] = true;
     471  	strm->internal->supported_actions[LZMA_FINISH] = true;
     472  
     473  	return LZMA_OK;
     474  }