aboutsummaryrefslogblamecommitdiff
path: root/tests/test_bcj_exact_size.c
blob: 0115ca60fc46faa5a199f90478df69bc6298d814 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                                               


                     








                                                                  

                                                  
 


                                   
 

                                                       
 



                                                                             
                                                      






                                                                   

                                                        
                                       

                                                                          
 

                                                                  
                                            
                                                                          









                                                                

                                                                       
                                        


                               
                                              



                                                
      



           
                      
 


                                                
                                                                    
                       
                                                            
                                                                     


                                                      
                       

                           
                                                                     
                                                                             
                         
                                        
                                   
      



          
                           
 

                                  



                                      
 
///////////////////////////////////////////////////////////////////////////////
//
/// \file       test_bcj_exact_size.c
/// \brief      Tests BCJ decoding when the output size is known
///
/// These tests fail with XZ Utils 5.0.3 and earlier.
//
//  Author:     Lasse Collin
//
//  This file has been put into the public domain.
//  You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////

#include "tests.h"


static void
test_exact_size(void)
{
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
	assert_skip("Encoder or decoder support disabled");
#else
	if (!lzma_filter_encoder_is_supported(LZMA_FILTER_POWERPC)
			|| !lzma_filter_decoder_is_supported(
				LZMA_FILTER_POWERPC))
		assert_skip("PowerPC BCJ encoder and/or decoder "
				"is disabled");

	// Something to be compressed
	const uint8_t in[16] = "0123456789ABCDEF";

	// in[] after compression
	uint8_t compressed[1024];
	size_t compressed_size = 0;

	// Output buffer for decompressing compressed[]
	uint8_t out[sizeof(in)];

	// Compress with PowerPC BCJ and LZMA2. PowerPC BCJ is used because
	// it has fixed 4-byte alignment which makes triggering the potential
	// bug easy.
	lzma_options_lzma opt_lzma2;
	assert_false(lzma_lzma_preset(&opt_lzma2, 0));

	lzma_filter filters[3] = {
		{ .id = LZMA_FILTER_POWERPC, .options = NULL },
		{ .id = LZMA_FILTER_LZMA2, .options = &opt_lzma2 },
		{ .id = LZMA_VLI_UNKNOWN, .options = NULL },
	};

	assert_lzma_ret(lzma_stream_buffer_encode(
			filters, LZMA_CHECK_CRC32, NULL,
			in, sizeof(in),
			compressed, &compressed_size, sizeof(compressed)),
		LZMA_OK);

	// Decompress so that we won't give more output space than
	// the Stream will need.
	lzma_stream strm = LZMA_STREAM_INIT;
	assert_lzma_ret(lzma_stream_decoder(&strm, 10 << 20, 0), LZMA_OK);

	strm.next_in = compressed;
	strm.next_out = out;

	while (true) {
		if (strm.total_in < compressed_size)
			strm.avail_in = 1;

		const lzma_ret ret = lzma_code(&strm, LZMA_RUN);
		if (ret == LZMA_STREAM_END) {
			assert_uint_eq(strm.total_in, compressed_size);
			assert_uint_eq(strm.total_out, sizeof(in));
			lzma_end(&strm);
			return;
		}

		assert_lzma_ret(ret, LZMA_OK);

		if (strm.total_out < sizeof(in))
			strm.avail_out = 1;
	}
#endif
}


static void
test_empty_block(void)
{
#ifndef HAVE_DECODERS
	assert_skip("Decoder support disabled");
#else
	// An empty file with one Block using PowerPC BCJ and LZMA2.
	size_t in_size;
	uint8_t *empty_bcj_lzma2 = tuktest_file_from_srcdir(
			"files/good-1-empty-bcj-lzma2.xz", &in_size);

	// Decompress without giving any output space.
	uint64_t memlimit = 1 << 20;
	uint8_t out[1];
	size_t in_pos = 0;
	size_t out_pos = 0;
	assert_lzma_ret(lzma_stream_buffer_decode(&memlimit, 0, NULL,
			empty_bcj_lzma2, &in_pos, in_size, out, &out_pos, 0),
		LZMA_OK);
	assert_uint_eq(in_pos, in_size);
	assert_uint_eq(out_pos, 0);
#endif
}


extern int
main(int argc, char **argv)
{
	tuktest_start(argc, argv);

	tuktest_run(test_exact_size);
	tuktest_run(test_empty_block);

	return tuktest_end();
}