(root)/
xz-5.4.5/
tests/
test_check.c
       1  ///////////////////////////////////////////////////////////////////////////////
       2  //
       3  /// \file       test_check.c
       4  /// \brief      Tests integrity checks
       5  //
       6  //  Authors:    Lasse Collin
       7  //              Jia Tan
       8  //
       9  //  This file has been put into the public domain.
      10  //  You can do whatever you want with this file.
      11  //
      12  ///////////////////////////////////////////////////////////////////////////////
      13  
      14  #include "tests.h"
      15  #include "mythread.h"
      16  
      17  
      18  // These must be specified as numbers so that the test works on EBCDIC
      19  // systems too.
      20  // static const uint8_t test_string[9] = "123456789";
      21  // static const uint8_t test_unaligned[12] = "xxx123456789";
      22  static const uint8_t test_string[9] = { 49, 50, 51, 52, 53, 54, 55, 56, 57 };
      23  static const uint8_t test_unaligned[12]
      24  		= { 120, 120, 120, 49, 50, 51, 52, 53, 54, 55, 56, 57 };
      25  
      26  // 2 MB is more than enough for the tests. Actually a tiny value would
      27  // work because we don't actually decompress the files, we only test
      28  // decoding of the Stream Header fields.
      29  #define TEST_CHECK_MEMLIMIT (2U << 20)
      30  
      31  static size_t no_check_size;
      32  static uint8_t *no_check_xz_data;
      33  
      34  static size_t unsupported_check_size;
      35  static uint8_t *unsupported_check_xz_data;
      36  
      37  #ifdef HAVE_CHECK_CRC32
      38  static size_t crc32_size;
      39  static uint8_t *crc32_xz_data;
      40  #endif
      41  
      42  #ifdef HAVE_CHECK_CRC64
      43  static size_t crc64_size;
      44  static uint8_t *crc64_xz_data;
      45  #endif
      46  
      47  #ifdef HAVE_CHECK_SHA256
      48  static size_t sha256_size;
      49  static uint8_t *sha256_xz_data;
      50  #endif
      51  
      52  
      53  #ifdef HAVE_CHECK_CRC64
      54  static const uint8_t *
      55  get_random256(uint32_t *seed)
      56  {
      57  	static uint8_t buf[256];
      58  
      59  	for (size_t i = 0; i < sizeof(buf); ++i) {
      60  		*seed = *seed * 1103515245 + 12345;
      61  		buf[i] = (uint8_t)(*seed >> 22);
      62  	}
      63  
      64  	return buf;
      65  }
      66  #endif
      67  
      68  
      69  static void
      70  test_lzma_crc32(void)
      71  {
      72  	// CRC32 is always enabled.
      73  	assert_true(lzma_check_is_supported(LZMA_CHECK_CRC32));
      74  
      75  	const uint32_t test_vector = 0xCBF43926;
      76  
      77  	// Test 1
      78  	assert_uint_eq(lzma_crc32(test_string, sizeof(test_string), 0),
      79  			test_vector);
      80  
      81  	// Test 2
      82  	assert_uint_eq(lzma_crc32(test_unaligned + 3, sizeof(test_string), 0),
      83  			test_vector);
      84  
      85  	// Test 3
      86  	uint32_t crc = 0;
      87  	for (size_t i = 0; i < sizeof(test_string); ++i)
      88  		crc = lzma_crc32(test_string + i, 1, crc);
      89  	assert_uint_eq(crc, test_vector);
      90  }
      91  
      92  
      93  static void
      94  test_lzma_crc64(void)
      95  {
      96  	// CRC64 can be disabled.
      97  	if (!lzma_check_is_supported(LZMA_CHECK_CRC64))
      98  		assert_skip("CRC64 support is disabled");
      99  
     100  	// If CRC64 is disabled then lzma_crc64() will be missing.
     101  	// Using an ifdef here avoids a linker error.
     102  #ifdef HAVE_CHECK_CRC64
     103  	const uint64_t test_vector = 0x995DC9BBDF1939FA;
     104  
     105  	// Test 1
     106  	assert_uint_eq(lzma_crc64(test_string, sizeof(test_string), 0),
     107  			test_vector);
     108  
     109  	// Test 2
     110  	assert_uint_eq(lzma_crc64(test_unaligned + 3, sizeof(test_string), 0),
     111  			test_vector);
     112  
     113  	// Test 3
     114  	uint64_t crc = 0;
     115  	for (size_t i = 0; i < sizeof(test_string); ++i)
     116  		crc = lzma_crc64(test_string + i, 1, crc);
     117  	assert_uint_eq(crc, test_vector);
     118  
     119  	// Test 4: The CLMUL implementation works on 16-byte chunks.
     120  	// Test combination of different start and end alignments
     121  	// and also short buffer lengths where special handling is needed.
     122  	uint32_t seed = 29;
     123  	crc = 0x96E30D5184B7FA2C; // Random initial value
     124  	for (size_t start = 0; start < 32; ++start)
     125  		for (size_t size = 1; size < 256 - 32; ++size)
     126  			crc = lzma_crc64(get_random256(&seed), size, crc);
     127  
     128  	assert_uint_eq(crc, 0x23AB787177231C9F);
     129  #endif
     130  }
     131  
     132  
     133  static void
     134  test_lzma_supported_checks(void)
     135  {
     136  	static const lzma_check expected_check_ids[] = {
     137  		LZMA_CHECK_NONE,
     138  #ifdef HAVE_CHECK_CRC32
     139  		LZMA_CHECK_CRC32,
     140  #endif
     141  #ifdef HAVE_CHECK_CRC64
     142  		LZMA_CHECK_CRC64,
     143  #endif
     144  #ifdef HAVE_CHECK_SHA256
     145  		LZMA_CHECK_SHA256,
     146  #endif
     147  	};
     148  
     149  	for (lzma_check i = 0; i <= LZMA_CHECK_ID_MAX + 1; i++) {
     150  		bool matched = false;
     151  		for (unsigned int j = 0; j < ARRAY_SIZE(expected_check_ids);
     152  				j++) {
     153  			if (expected_check_ids[j] == i) {
     154  				matched = true;
     155  				break;
     156  			}
     157  		}
     158  
     159  		if (matched)
     160  			assert_true(lzma_check_is_supported(i));
     161  		else
     162  			assert_false(lzma_check_is_supported(i));
     163  	}
     164  }
     165  
     166  
     167  static void
     168  test_lzma_check_size(void)
     169  {
     170  	// Expected check sizes taken from src/liblzma/api/lzma/check.h
     171  	static const uint32_t expected_check_sizes[] = {
     172  			0, 4, 4, 4, 8, 8, 8, 16, 16, 16,
     173  			32, 32, 32, 64, 64, 64
     174  	};
     175  
     176  	for (lzma_check i = 0; i < ARRAY_SIZE(expected_check_sizes); i++)
     177  		assert_uint_eq(expected_check_sizes[i], lzma_check_size(i));
     178  
     179  	assert_uint_eq(lzma_check_size(INVALID_LZMA_CHECK_ID), UINT32_MAX);
     180  }
     181  
     182  
     183  // Test the single threaded decoder for lzma_get_check
     184  static void
     185  test_lzma_get_check_st(void)
     186  {
     187  #ifndef HAVE_DECODERS
     188  	assert_skip("Decoder support disabled");
     189  #else
     190  	const uint32_t flags = LZMA_TELL_ANY_CHECK |
     191  			LZMA_TELL_UNSUPPORTED_CHECK |
     192  			LZMA_TELL_NO_CHECK;
     193  
     194  	uint8_t outbuf[128];
     195  	lzma_stream strm = LZMA_STREAM_INIT;
     196  
     197  	// Test a file with no integrity check:
     198  	assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT,
     199  			flags), LZMA_OK);
     200  	strm.next_in = no_check_xz_data;
     201  	strm.avail_in = no_check_size;
     202  	strm.next_out = outbuf;
     203  	strm.avail_out = sizeof(outbuf);
     204  
     205  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_NO_CHECK);
     206  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_NONE);
     207  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     208  
     209  	// Test a file with an unsupported integrity check type:
     210  	assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT,
     211  			flags), LZMA_OK);
     212  	strm.next_in = unsupported_check_xz_data;
     213  	strm.avail_in = unsupported_check_size;
     214  	strm.next_out = outbuf;
     215  	strm.avail_out = sizeof(outbuf);
     216  
     217  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_UNSUPPORTED_CHECK);
     218  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     219  
     220  	// Test a file with CRC32 as the integrity check:
     221  #ifdef HAVE_CHECK_CRC32
     222  	assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT,
     223  			flags), LZMA_OK);
     224  	strm.next_in = crc32_xz_data;
     225  	strm.avail_in = crc32_size;
     226  	strm.next_out = outbuf;
     227  	strm.avail_out = sizeof(outbuf);
     228  
     229  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK);
     230  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC32);
     231  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     232  #endif
     233  
     234  	// Test a file with CRC64 as the integrity check:
     235  #ifdef HAVE_CHECK_CRC64
     236  	assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT,
     237  			flags), LZMA_OK);
     238  	strm.next_in = crc64_xz_data;
     239  	strm.avail_in = crc64_size;
     240  	strm.next_out = outbuf;
     241  	strm.avail_out = sizeof(outbuf);
     242  
     243  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK);
     244  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC64);
     245  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     246  #endif
     247  
     248  	// Test a file with SHA-256 as the integrity check:
     249  #ifdef HAVE_CHECK_SHA256
     250  	assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT,
     251  			flags), LZMA_OK);
     252  	strm.next_in = sha256_xz_data;
     253  	strm.avail_in = sha256_size;
     254  	strm.next_out = outbuf;
     255  	strm.avail_out = sizeof(outbuf);
     256  
     257  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK);
     258  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_SHA256);
     259  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     260  #endif
     261  
     262  	lzma_end(&strm);
     263  #endif
     264  }
     265  
     266  
     267  static void
     268  test_lzma_get_check_mt(void)
     269  {
     270  #ifndef MYTHREAD_ENABLED
     271  	assert_skip("Threading support disabled");
     272  #elif !defined(HAVE_DECODERS)
     273  	assert_skip("Decoder support disabled");
     274  #else
     275  	const uint32_t flags = LZMA_TELL_ANY_CHECK |
     276  			LZMA_TELL_UNSUPPORTED_CHECK |
     277  			LZMA_TELL_NO_CHECK;
     278  
     279  	const lzma_mt options = {
     280  		.flags = flags,
     281  		.threads = 2,
     282  		.timeout = 0,
     283  		.memlimit_threading = TEST_CHECK_MEMLIMIT,
     284  		.memlimit_stop = TEST_CHECK_MEMLIMIT
     285  	};
     286  
     287  	uint8_t outbuf[128];
     288  	lzma_stream strm = LZMA_STREAM_INIT;
     289  
     290  	// Test a file with no integrity check:
     291  	assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK);
     292  	strm.next_in = no_check_xz_data;
     293  	strm.avail_in = no_check_size;
     294  	strm.next_out = outbuf;
     295  	strm.avail_out = sizeof(outbuf);
     296  
     297  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_NO_CHECK);
     298  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_NONE);
     299  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     300  
     301  	// Test a file with an unsupported integrity check type:
     302  	assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK);
     303  	strm.next_in = unsupported_check_xz_data;
     304  	strm.avail_in = unsupported_check_size;
     305  	strm.next_out = outbuf;
     306  	strm.avail_out = sizeof(outbuf);
     307  
     308  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_UNSUPPORTED_CHECK);
     309  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     310  
     311  	// Test a file with CRC32 as the integrity check:
     312  #ifdef HAVE_CHECK_CRC32
     313  	assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK);
     314  	strm.next_in = crc32_xz_data;
     315  	strm.avail_in = crc32_size;
     316  	strm.next_out = outbuf;
     317  	strm.avail_out = sizeof(outbuf);
     318  
     319  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK);
     320  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC32);
     321  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     322  #endif
     323  
     324  	// Test a file with CRC64 as the integrity check:
     325  #ifdef HAVE_CHECK_CRC64
     326  	assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK);
     327  	strm.next_in = crc64_xz_data;
     328  	strm.avail_in = crc64_size;
     329  	strm.next_out = outbuf;
     330  	strm.avail_out = sizeof(outbuf);
     331  
     332  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK);
     333  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC64);
     334  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     335  #endif
     336  
     337  	// Test a file with SHA-256 as the integrity check:
     338  #ifdef HAVE_CHECK_SHA256
     339  	assert_lzma_ret(lzma_stream_decoder_mt(&strm,&options), LZMA_OK);
     340  	strm.next_in = sha256_xz_data;
     341  	strm.avail_in = sha256_size;
     342  	strm.next_out = outbuf;
     343  	strm.avail_out = sizeof(outbuf);
     344  
     345  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK);
     346  	assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_SHA256);
     347  	assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
     348  #endif
     349  
     350  	lzma_end(&strm);
     351  #endif
     352  }
     353  
     354  
     355  extern int
     356  main(int argc, char **argv)
     357  {
     358  	tuktest_start(argc, argv);
     359  
     360  	no_check_xz_data = tuktest_file_from_srcdir(
     361  			"files/good-1-check-none.xz", &no_check_size);
     362  
     363  	unsupported_check_xz_data = tuktest_file_from_srcdir(
     364  			"files/unsupported-check.xz",
     365  			&unsupported_check_size);
     366  
     367  #ifdef HAVE_CHECK_CRC32
     368  	crc32_xz_data = tuktest_file_from_srcdir(
     369  			"files/good-1-check-crc32.xz", &crc32_size);
     370  #endif
     371  
     372  #ifdef HAVE_CHECK_CRC64
     373  	crc64_xz_data = tuktest_file_from_srcdir(
     374  			"files/good-1-check-crc64.xz", &crc64_size);
     375  #endif
     376  
     377  #ifdef HAVE_CHECK_SHA256
     378  	sha256_xz_data = tuktest_file_from_srcdir(
     379  			"files/good-1-check-sha256.xz", &sha256_size);
     380  #endif
     381  
     382  	tuktest_run(test_lzma_crc32);
     383  	tuktest_run(test_lzma_crc64);
     384  	tuktest_run(test_lzma_supported_checks);
     385  	tuktest_run(test_lzma_check_size);
     386  	tuktest_run(test_lzma_get_check_st);
     387  	tuktest_run(test_lzma_get_check_mt);
     388  
     389  	return tuktest_end();
     390  }