aboutsummaryrefslogblamecommitdiff
path: root/tests/test_block_header.c
blob: 2f0184ac726625d91d4e4a40b57f516500fcb16d (plain) (tree)
1
2
3
4
5
6
7
8
9




                                                                               
                            
  

                                                  





                                                                               
                                               

                                  
 

                                  
                                      
         
                                       


          
 
                                     
         
                                        
                                     
            
                                       
         

  
 
                                      
         

                                      
            
                                      

                                
                                      
                                
            
                                        
                                     
            
                                       
         


  
                                      












                                      
                                        
                                     
            
                                       
         
  

 

           
 

                                                                      
 
                                                  
                                          
                                                           
 


                                                                

                                                                              
 



                                                         
 
                                                      
                                                 
                                                                           
 
                                                     
                                                         





           
                                     
                                         

                                                      
                                
          
 

                                                               
 
                                             

                                                               
 
                                             

                                                               
 
                                            
                                                                         
 

                                                  
                                                                         
 
                                          
                                                                         
 
                                                             

                                                               
 



                                                                         
                                                                         
 
                                                         
                                            
                                                                         
 
                                                           

                                                               



           
           
 
                                     
                                          

                                                      
                                        
          
 
                                                                         
               
 

                                                 
                                                                         
               
 




                                                                      



           
           
 
                                     
                                          

                                                      
                                       
          
 
                                                                         
                                       

                                                                      
 
                                                  


                                                                
 

                     

                                                                              



                                                

                                                                              




                                                                      
                                                      
                                                                           

                                                                              
                       
 

                                                    
                                                      
                                                                           

                                                                              
                                                    


 

                           
 
                                  
 



                                                                              
 







                                                           
 
///////////////////////////////////////////////////////////////////////////////
//
/// \file       test_block_header.c
/// \brief      Tests Block Header coders
//
//  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 uint8_t buf[LZMA_BLOCK_HEADER_SIZE_MAX];
static lzma_block known_options;
static lzma_block decoded_options;

static lzma_options_lzma opt_lzma;

static lzma_filter filters_none[1] = {
	{
		.id = LZMA_VLI_UNKNOWN,
	},
};


static lzma_filter filters_one[2] = {
	{
		.id = LZMA_FILTER_LZMA2,
		.options = &opt_lzma,
	}, {
		.id = LZMA_VLI_UNKNOWN,
	}
};


static lzma_filter filters_four[5] = {
	{
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_LZMA2,
		.options = &opt_lzma,
	}, {
		.id = LZMA_VLI_UNKNOWN,
	}
};


static lzma_filter filters_five[6] = {
	{
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_X86,
		.options = NULL,
	}, {
		.id = LZMA_FILTER_LZMA2,
		.options = &opt_lzma,
	}, {
		.id = LZMA_VLI_UNKNOWN,
	}
};


static void
code(void)
{
	assert_lzma_ret(lzma_block_header_encode(&known_options, buf),
			LZMA_OK);

	lzma_filter filters[LZMA_FILTERS_MAX + 1];
	memcrap(filters, sizeof(filters));
	memcrap(&decoded_options, sizeof(decoded_options));

	decoded_options.header_size = known_options.header_size;
	decoded_options.check = known_options.check;
	decoded_options.filters = filters;
	assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
			LZMA_OK);

	assert_uint_eq(decoded_options.compressed_size,
			known_options.compressed_size);
	assert_uint_eq(decoded_options.uncompressed_size,
			known_options.uncompressed_size);

	for (size_t i = 0; known_options.filters[i].id
			!= LZMA_VLI_UNKNOWN; ++i)
		assert_uint_eq(filters[i].id, known_options.filters[i].id);

	for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i)
		free(decoded_options.filters[i].options);
}


static void
test1(void)
{
	known_options = (lzma_block){
		.check = LZMA_CHECK_NONE,
		.compressed_size = LZMA_VLI_UNKNOWN,
		.uncompressed_size = LZMA_VLI_UNKNOWN,
		.filters = NULL,
	};

	assert_lzma_ret(lzma_block_header_size(&known_options),
			LZMA_PROG_ERROR);

	known_options.filters = filters_none;
	assert_lzma_ret(lzma_block_header_size(&known_options),
			LZMA_PROG_ERROR);

	known_options.filters = filters_five;
	assert_lzma_ret(lzma_block_header_size(&known_options),
			LZMA_PROG_ERROR);

	known_options.filters = filters_one;
	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);

	// Some invalid value, which gets ignored.
	known_options.check = (lzma_check)(99);
	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);

	known_options.compressed_size = 5;
	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);

	known_options.compressed_size = 0; // Cannot be zero.
	assert_lzma_ret(lzma_block_header_size(&known_options),
			LZMA_PROG_ERROR);

	// LZMA_VLI_MAX is too big to keep the total size of the Block
	// a valid VLI, but lzma_block_header_size() is not meant
	// to validate it. (lzma_block_header_encode() must validate it.)
	known_options.compressed_size = LZMA_VLI_MAX;
	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);

	known_options.compressed_size = LZMA_VLI_UNKNOWN;
	known_options.uncompressed_size = 0;
	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);

	known_options.uncompressed_size = LZMA_VLI_MAX + 1;
	assert_lzma_ret(lzma_block_header_size(&known_options),
			LZMA_PROG_ERROR);
}


static void
test2(void)
{
	known_options = (lzma_block){
		.check = LZMA_CHECK_CRC32,
		.compressed_size = LZMA_VLI_UNKNOWN,
		.uncompressed_size = LZMA_VLI_UNKNOWN,
		.filters = filters_four,
	};

	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
	code();

	known_options.compressed_size = 123456;
	known_options.uncompressed_size = 234567;
	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
	code();

	// We can make the sizes smaller while keeping the header size
	// the same.
	known_options.compressed_size = 12;
	known_options.uncompressed_size = 23;
	code();
}


static void
test3(void)
{
	known_options = (lzma_block){
		.check = LZMA_CHECK_CRC32,
		.compressed_size = LZMA_VLI_UNKNOWN,
		.uncompressed_size = LZMA_VLI_UNKNOWN,
		.filters = filters_one,
	};

	assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
	known_options.header_size += 4;
	assert_lzma_ret(lzma_block_header_encode(&known_options, buf),
			LZMA_OK);

	lzma_filter filters[LZMA_FILTERS_MAX + 1];
	decoded_options.header_size = known_options.header_size;
	decoded_options.check = known_options.check;
	decoded_options.filters = filters;

	// Wrong size
	++buf[0];
	assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
			LZMA_PROG_ERROR);
	--buf[0];

	// Wrong CRC32
	buf[known_options.header_size - 1] ^= 1;
	assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
			LZMA_DATA_ERROR);
	buf[known_options.header_size - 1] ^= 1;

	// Unsupported filter
	// NOTE: This may need updating when new IDs become supported.
	buf[2] ^= 0x1F;
	write32le(buf + known_options.header_size - 4,
			lzma_crc32(buf, known_options.header_size - 4, 0));
	assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
			LZMA_OPTIONS_ERROR);
	buf[2] ^= 0x1F;

	// Non-nul Padding
	buf[known_options.header_size - 4 - 1] ^= 1;
	write32le(buf + known_options.header_size - 4,
			lzma_crc32(buf, known_options.header_size - 4, 0));
	assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
			LZMA_OPTIONS_ERROR);
	buf[known_options.header_size - 4 - 1] ^= 1;
}


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

	if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86)
			|| !lzma_filter_decoder_is_supported(LZMA_FILTER_X86))
		tuktest_early_skip("x86 BCJ encoder and/or decoder "
				"is disabled");

	if (lzma_lzma_preset(&opt_lzma, 1))
		tuktest_error("lzma_lzma_preset() failed");

	tuktest_run(test1);
	tuktest_run(test2);
	tuktest_run(test3);

	return tuktest_end();
}