(root)/
xz-5.4.5/
tests/
test_index.c
       1  ///////////////////////////////////////////////////////////////////////////////
       2  //
       3  /// \file       test_index.c
       4  /// \brief      Tests functions handling the lzma_index structure
       5  ///
       6  /// \todo       Implement tests for lzma_file_info_decoder
       7  //
       8  //  Authors:    Jia Tan
       9  //              Lasse Collin
      10  //
      11  //
      12  //  This file has been put into the public domain.
      13  //  You can do whatever you want with this file.
      14  //
      15  ///////////////////////////////////////////////////////////////////////////////
      16  
      17  #include "tests.h"
      18  
      19  // liblzma internal header file needed for:
      20  // UNPADDED_SIZE_MIN
      21  // UNPADDED_SIZE_MAX
      22  // vli_ceil4
      23  #include "common/index.h"
      24  
      25  
      26  #define MEMLIMIT (UINT64_C(1) << 20)
      27  
      28  static uint8_t *decode_buffer;
      29  static size_t decode_buffer_size = 0;
      30  static lzma_index *decode_test_index;
      31  
      32  
      33  static void
      34  test_lzma_index_memusage(void)
      35  {
      36  	// The return value from lzma_index_memusage is an approximation
      37  	// of the amount of memory needed for lzma_index for a given
      38  	// amount of Streams and Blocks. It will be an upperbound,
      39  	// so this test will mostly sanity check and error check the
      40  	// function.
      41  
      42  	// The maximum number of Streams should be UINT32_MAX in the
      43  	// current implementation even though the parameter is lzma_vli.
      44  	assert_uint_eq(lzma_index_memusage((lzma_vli)UINT32_MAX + 1, 1),
      45  			UINT64_MAX);
      46  
      47  	// The maximum number of Blocks should be LZMA_VLI_MAX
      48  	assert_uint_eq(lzma_index_memusage(1, LZMA_VLI_MAX), UINT64_MAX);
      49  
      50  	// Number of Streams must be non-zero
      51  	assert_uint_eq(lzma_index_memusage(0, 1), UINT64_MAX);
      52  
      53  	// Number of Blocks CAN be zero
      54  	assert_uint(lzma_index_memusage(1, 0), !=, UINT64_MAX);
      55  
      56  	// Arbitrary values for Stream and Block should work without error
      57  	// and should always increase
      58  	uint64_t previous = 1;
      59  	lzma_vli streams = 1;
      60  	lzma_vli blocks = 1;
      61  
      62  	// Test 100 different increasing values for Streams and Block
      63  	for (int i = 0; i < 100; i++) {
      64  		uint64_t current = lzma_index_memusage(streams, blocks);
      65  		assert_uint(current, >, previous);
      66  		previous = current;
      67  		streams += 29;
      68  		blocks += 107;
      69  	}
      70  
      71  	// Force integer overflow in calculation (should result in an error)
      72  	assert_uint_eq(lzma_index_memusage(UINT32_MAX, LZMA_VLI_MAX),
      73  			UINT64_MAX);
      74  }
      75  
      76  
      77  static void
      78  test_lzma_index_memused(void)
      79  {
      80  	// Very similar to test_lzma_index_memusage above since
      81  	// lzma_index_memused is essentially a wrapper for
      82  	// lzma_index_memusage
      83  	lzma_index *idx = lzma_index_init(NULL);
      84  	assert_true(idx != NULL);
      85  
      86  	// Test with empty Index
      87  	assert_uint(lzma_index_memused(idx), <, UINT64_MAX);
      88  
      89  	// Append small Blocks and then test again (should pass).
      90  	for (lzma_vli i = 0; i < 10; i++)
      91  		assert_lzma_ret(lzma_index_append(idx, NULL,
      92  				UNPADDED_SIZE_MIN, 1), LZMA_OK);
      93  
      94  	assert_uint(lzma_index_memused(idx), <, UINT64_MAX);
      95  
      96  	lzma_index_end(idx, NULL);
      97  }
      98  
      99  
     100  static void
     101  test_lzma_index_append(void)
     102  {
     103  	// Basic input-ouput test done here.
     104  	// Less trivial tests for this function are done throughout
     105  	// other tests.
     106  
     107  	// First test with NULL lzma_index
     108  	assert_lzma_ret(lzma_index_append(NULL, NULL, UNPADDED_SIZE_MIN,
     109  			1), LZMA_PROG_ERROR);
     110  
     111  	lzma_index *idx = lzma_index_init(NULL);
     112  	assert_true(idx != NULL);
     113  
     114  	// Test with invalid Unpadded Size
     115  	assert_lzma_ret(lzma_index_append(idx, NULL,
     116  			UNPADDED_SIZE_MIN - 1, 1), LZMA_PROG_ERROR);
     117  	assert_lzma_ret(lzma_index_append(idx, NULL,
     118  			UNPADDED_SIZE_MAX + 1, 1), LZMA_PROG_ERROR);
     119  
     120  	// Test with invalid Uncompressed Size
     121  	assert_lzma_ret(lzma_index_append(idx, NULL,
     122  			UNPADDED_SIZE_MAX, LZMA_VLI_MAX + 1),
     123  			LZMA_PROG_ERROR);
     124  
     125  	// Test expected successful Block appends
     126  	assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MIN,
     127  			1), LZMA_OK);
     128  	assert_lzma_ret(lzma_index_append(idx, NULL,
     129  			UNPADDED_SIZE_MIN * 2,
     130  			2), LZMA_OK);
     131  	assert_lzma_ret(lzma_index_append(idx, NULL,
     132  			UNPADDED_SIZE_MIN * 3,
     133  			3), LZMA_OK);
     134  
     135  	lzma_index_end(idx, NULL);
     136  
     137  	// Test compressed .xz file size growing too large. This also tests
     138  	// a failing assert fixed in 68bda971bb8b666a009331455fcedb4e18d837a4.
     139  	// Should result in LZMA_DATA_ERROR.
     140  	idx = lzma_index_init(NULL);
     141  
     142  	// The calculation for maximum unpadded size is to make room for the
     143  	// second stream when lzma_index_cat() is called. The
     144  	// 4 * LZMA_STREAM_HEADER_SIZE is for the header and footer of
     145  	// both streams. The extra 24 bytes are for the size of the indexes
     146  	// for both streams. This allows us to maximize the unpadded sum
     147  	// during the lzma_index_append() call after the indexes have been
     148  	// concatenated.
     149  	assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MAX
     150  			- ((4 * LZMA_STREAM_HEADER_SIZE) + 24), 1), LZMA_OK);
     151  
     152  	lzma_index *second = lzma_index_init(NULL);
     153  	assert_true(second != NULL);
     154  
     155  	assert_lzma_ret(lzma_index_cat(second, idx, NULL), LZMA_OK);
     156  
     157  	assert_lzma_ret(lzma_index_append(second, NULL, UNPADDED_SIZE_MAX, 1),
     158  			LZMA_DATA_ERROR);
     159  
     160  	lzma_index_end(second, NULL);
     161  
     162  	// Test uncompressed size growing too large.
     163  	// Should result in LZMA_DATA_ERROR.
     164  	idx = lzma_index_init(NULL);
     165  
     166  	assert_lzma_ret(lzma_index_append(idx, NULL,
     167  			UNPADDED_SIZE_MIN, LZMA_VLI_MAX), LZMA_OK);
     168  	assert_lzma_ret(lzma_index_append(idx, NULL,
     169  			UNPADDED_SIZE_MIN, 1), LZMA_DATA_ERROR);
     170  
     171  	lzma_index_end(idx, NULL);
     172  
     173  	// Currently not testing for error case when the size of the Index
     174  	// grows too large to be stored. This was not practical to test for
     175  	// since too many Blocks needed to be created to cause this.
     176  }
     177  
     178  
     179  static void
     180  test_lzma_index_stream_flags(void)
     181  {
     182  	// Only trivial tests done here testing for basic functionality.
     183  	// More in-depth testing for this function will be done in
     184  	// test_lzma_index_checks.
     185  
     186  	// Testing for NULL inputs
     187  	assert_lzma_ret(lzma_index_stream_flags(NULL, NULL),
     188  			LZMA_PROG_ERROR);
     189  
     190  	lzma_index *idx = lzma_index_init(NULL);
     191  	assert_true(idx != NULL);
     192  
     193  	assert_lzma_ret(lzma_index_stream_flags(idx, NULL),
     194  			LZMA_PROG_ERROR);
     195  
     196  	lzma_stream_flags stream_flags = {
     197  		.version = 0,
     198  		.backward_size = LZMA_BACKWARD_SIZE_MIN,
     199  		.check = LZMA_CHECK_CRC32
     200  	};
     201  
     202  	assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
     203  			LZMA_OK);
     204  
     205  	lzma_index_end(idx, NULL);
     206  }
     207  
     208  
     209  static void
     210  test_lzma_index_checks(void)
     211  {
     212  	// Tests should still pass, even if some of the check types
     213  	// are disabled.
     214  	lzma_index *idx = lzma_index_init(NULL);
     215  	assert_true(idx != NULL);
     216  
     217  	lzma_stream_flags stream_flags = {
     218  		.version = 0,
     219  		.backward_size = LZMA_BACKWARD_SIZE_MIN,
     220  		.check = LZMA_CHECK_NONE
     221  	};
     222  
     223  	// First set the check type to None
     224  	assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
     225  			LZMA_OK);
     226  	assert_uint_eq(lzma_index_checks(idx),
     227  			UINT32_C(1) << LZMA_CHECK_NONE);
     228  
     229  	// Set the check type to CRC32 and repeat
     230  	stream_flags.check = LZMA_CHECK_CRC32;
     231  	assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
     232  			LZMA_OK);
     233  	assert_uint_eq(lzma_index_checks(idx),
     234  			UINT32_C(1) << LZMA_CHECK_CRC32);
     235  
     236  	// Set the check type to CRC64 and repeat
     237  	stream_flags.check = LZMA_CHECK_CRC64;
     238  	assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
     239  			LZMA_OK);
     240  	assert_uint_eq(lzma_index_checks(idx),
     241  			UINT32_C(1) << LZMA_CHECK_CRC64);
     242  
     243  	// Set the check type to SHA256 and repeat
     244  	stream_flags.check = LZMA_CHECK_SHA256;
     245  	assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
     246  			LZMA_OK);
     247  	assert_uint_eq(lzma_index_checks(idx),
     248  			UINT32_C(1) << LZMA_CHECK_SHA256);
     249  
     250  	// Create second lzma_index and cat to first
     251  	lzma_index *second = lzma_index_init(NULL);
     252  	assert_true(second != NULL);
     253  
     254  	// Set the check type to CRC32 for the second lzma_index
     255  	stream_flags.check = LZMA_CHECK_CRC32;
     256  	assert_lzma_ret(lzma_index_stream_flags(second, &stream_flags),
     257  			LZMA_OK);
     258  
     259  	assert_uint_eq(lzma_index_checks(second),
     260  			UINT32_C(1) << LZMA_CHECK_CRC32);
     261  
     262  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
     263  
     264  	// Index should now have both CRC32 and SHA256
     265  	assert_uint_eq(lzma_index_checks(idx),
     266  			(UINT32_C(1) << LZMA_CHECK_CRC32) |
     267  			(UINT32_C(1) << LZMA_CHECK_SHA256));
     268  
     269  	// Change the check type of the second Stream to SHA256
     270  	stream_flags.check = LZMA_CHECK_SHA256;
     271  	assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
     272  			LZMA_OK);
     273  
     274  	// Index should now have only SHA256
     275  	assert_uint_eq(lzma_index_checks(idx),
     276  			UINT32_C(1) << LZMA_CHECK_SHA256);
     277  
     278  	// Test with a third Stream
     279  	lzma_index *third = lzma_index_init(NULL);
     280  	assert_true(third != NULL);
     281  
     282  	stream_flags.check = LZMA_CHECK_CRC64;
     283  	assert_lzma_ret(lzma_index_stream_flags(third, &stream_flags),
     284  			LZMA_OK);
     285  
     286  	assert_uint_eq(lzma_index_checks(third),
     287  			UINT32_C(1) << LZMA_CHECK_CRC64);
     288  
     289  	assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK);
     290  
     291  	// Index should now have CRC64 and SHA256
     292  	assert_uint_eq(lzma_index_checks(idx),
     293  			(UINT32_C(1) << LZMA_CHECK_CRC64) |
     294  			(UINT32_C(1) << LZMA_CHECK_SHA256));
     295  
     296  	lzma_index_end(idx, NULL);
     297  }
     298  
     299  
     300  static void
     301  test_lzma_index_stream_padding(void)
     302  {
     303  	// Test NULL lzma_index
     304  	assert_lzma_ret(lzma_index_stream_padding(NULL, 0),
     305  			LZMA_PROG_ERROR);
     306  
     307  	lzma_index *idx = lzma_index_init(NULL);
     308  	assert_true(idx != NULL);
     309  
     310  	// Test Stream Padding not a multiple of 4
     311  	assert_lzma_ret(lzma_index_stream_padding(idx, 3),
     312  			LZMA_PROG_ERROR);
     313  
     314  	// Test Stream Padding too large
     315  	assert_lzma_ret(lzma_index_stream_padding(idx, LZMA_VLI_MAX - 3),
     316  			LZMA_DATA_ERROR);
     317  
     318  	// Test Stream Padding valid
     319  	assert_lzma_ret(lzma_index_stream_padding(idx, 0x1000),
     320  			LZMA_OK);
     321  	assert_lzma_ret(lzma_index_stream_padding(idx, 4),
     322  			LZMA_OK);
     323  	assert_lzma_ret(lzma_index_stream_padding(idx, 0),
     324  			LZMA_OK);
     325  
     326  	// Test Stream Padding causing the file size to grow too large
     327  	assert_lzma_ret(lzma_index_append(idx, NULL,
     328  			LZMA_VLI_MAX - 0x1000, 1), LZMA_OK);
     329  	assert_lzma_ret(lzma_index_stream_padding(idx, 0x1000),
     330  			LZMA_DATA_ERROR);
     331  
     332  	lzma_index_end(idx, NULL);
     333  }
     334  
     335  
     336  static void
     337  test_lzma_index_stream_count(void)
     338  {
     339  	lzma_index *idx = lzma_index_init(NULL);
     340  	assert_true(idx != NULL);
     341  
     342  	assert_uint_eq(lzma_index_stream_count(idx), 1);
     343  
     344  	// Appending Blocks should not change the Stream count value
     345  	assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MIN,
     346  			1), LZMA_OK);
     347  
     348  	assert_uint_eq(lzma_index_stream_count(idx), 1);
     349  
     350  	// Test with multiple Streams
     351  	for (uint32_t i = 0; i < 100; i++) {
     352  		lzma_index *idx_cat = lzma_index_init(NULL);
     353  		assert_true(idx != NULL);
     354  		assert_lzma_ret(lzma_index_cat(idx, idx_cat, NULL), LZMA_OK);
     355  		assert_uint_eq(lzma_index_stream_count(idx), i + 2);
     356  	}
     357  
     358  	lzma_index_end(idx, NULL);
     359  }
     360  
     361  
     362  static void
     363  test_lzma_index_block_count(void)
     364  {
     365  	lzma_index *idx = lzma_index_init(NULL);
     366  	assert_true(idx != NULL);
     367  
     368  	assert_uint_eq(lzma_index_block_count(idx), 0);
     369  
     370  	const uint32_t iterations = 0x1000;
     371  	for (uint32_t i = 0; i < iterations; i++) {
     372  		assert_lzma_ret(lzma_index_append(idx, NULL,
     373  				UNPADDED_SIZE_MIN, 1), LZMA_OK);
     374  		assert_uint_eq(lzma_index_block_count(idx), i + 1);
     375  	}
     376  
     377  	// Create new lzma_index with a few Blocks
     378  	lzma_index *second = lzma_index_init(NULL);
     379  	assert_true(second != NULL);
     380  
     381  	assert_lzma_ret(lzma_index_append(second, NULL,
     382  			UNPADDED_SIZE_MIN, 1), LZMA_OK);
     383  	assert_lzma_ret(lzma_index_append(second, NULL,
     384  			UNPADDED_SIZE_MIN, 1), LZMA_OK);
     385  	assert_lzma_ret(lzma_index_append(second, NULL,
     386  			UNPADDED_SIZE_MIN, 1), LZMA_OK);
     387  
     388  	assert_uint_eq(lzma_index_block_count(second), 3);
     389  
     390  	// Concatenate the lzma_indexes together and the result should have
     391  	// the sum of the two individual counts.
     392  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
     393  	assert_uint_eq(lzma_index_block_count(idx), iterations + 3);
     394  
     395  	assert_lzma_ret(lzma_index_append(idx, NULL,
     396  			UNPADDED_SIZE_MIN, 1), LZMA_OK);
     397  
     398  	assert_uint_eq(lzma_index_block_count(idx), iterations + 4);
     399  
     400  	lzma_index_end(idx, NULL);
     401  }
     402  
     403  
     404  static void
     405  test_lzma_index_size(void)
     406  {
     407  	lzma_index *idx = lzma_index_init(NULL);
     408  	assert_true(idx != NULL);
     409  
     410  	// Base size should be:
     411  	// 1 byte Index Indicator
     412  	// 1 byte Number of Records
     413  	// 0 bytes Records
     414  	// 2 bytes Index Padding
     415  	// 4 bytes CRC32
     416  	// Total: 8 bytes
     417  	assert_uint_eq(lzma_index_size(idx), 8);
     418  
     419  	assert_lzma_ret(lzma_index_append(idx, NULL,
     420  			UNPADDED_SIZE_MIN, 1), LZMA_OK);
     421  
     422  	// New size should be:
     423  	// 1 byte Index Indicator
     424  	// 1 byte Number of Records
     425  	// 2 bytes Records
     426  	// 0 bytes Index Padding
     427  	// 4 bytes CRC32
     428  	// Total: 8 bytes
     429  	assert_uint_eq(lzma_index_size(idx), 8);
     430  
     431  	assert_lzma_ret(lzma_index_append(idx, NULL,
     432  			LZMA_VLI_MAX / 4, LZMA_VLI_MAX / 4), LZMA_OK);
     433  
     434  	// New size should be:
     435  	// 1 byte Index Indicator
     436  	// 1 byte Number of Records
     437  	// 20 bytes Records
     438  	// 2 bytes Index Padding
     439  	// 4 bytes CRC32
     440  	// Total: 28 bytes
     441  	assert_uint_eq(lzma_index_size(idx), 28);
     442  
     443  	lzma_index_end(idx, NULL);
     444  }
     445  
     446  
     447  static void
     448  test_lzma_index_stream_size(void)
     449  {
     450  	lzma_index *idx = lzma_index_init(NULL);
     451  	assert_true(idx != NULL);
     452  
     453  	// Stream size calculated by:
     454  	// Size of Stream Header (12 bytes)
     455  	// Size of all Blocks
     456  	// Size of the Index
     457  	// Size of the Stream Footer (12 bytes)
     458  
     459  	// First test with empty Index
     460  	// Stream size should be:
     461  	// Size of Stream Header - 12 bytes
     462  	// Size of all Blocks - 0 bytes
     463  	// Size of Index - 8 bytes
     464  	// Size of Stream Footer - 12 bytes
     465  	// Total: 32 bytes
     466  	assert_uint_eq(lzma_index_stream_size(idx), 32);
     467  
     468  	// Next, append a few Blocks and retest
     469  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     470  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     471  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     472  
     473  	// Stream size should be:
     474  	// Size of Stream Header - 12 bytes
     475  	// Size of all Blocks - 3000 bytes
     476  	// Size of Index - 16 bytes
     477  	// Size of Stream Footer - 12 bytes
     478  	// Total: 3040 bytes
     479  	assert_uint_eq(lzma_index_stream_size(idx), 3040);
     480  
     481  	lzma_index *second = lzma_index_init(NULL);
     482  	assert_true(second != NULL);
     483  
     484  	assert_uint_eq(lzma_index_stream_size(second), 32);
     485  	assert_lzma_ret(lzma_index_append(second, NULL, 1000, 1), LZMA_OK);
     486  
     487  	// Stream size should be:
     488  	// Size of Stream Header - 12 bytes
     489  	// Size of all Blocks - 1000 bytes
     490  	// Size of Index - 12 bytes
     491  	// Size of Stream Footer - 12 bytes
     492  	// Total: 1036 bytes
     493  	assert_uint_eq(lzma_index_stream_size(second), 1036);
     494  
     495  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
     496  
     497  	// Stream size should be:
     498  	// Size of Stream Header - 12 bytes
     499  	// Size of all Blocks - 4000 bytes
     500  	// Size of Index - 20 bytes
     501  	// Size of Stream Footer - 12 bytes
     502  	// Total: 4044 bytes
     503  	assert_uint_eq(lzma_index_stream_size(idx), 4044);
     504  
     505  	lzma_index_end(idx, NULL);
     506  }
     507  
     508  
     509  static void
     510  test_lzma_index_total_size(void)
     511  {
     512  	lzma_index *idx = lzma_index_init(NULL);
     513  	assert_true(idx != NULL);
     514  
     515  	// First test empty lzma_index.
     516  	// Result should be 0 since no Blocks have been added.
     517  	assert_uint_eq(lzma_index_total_size(idx), 0);
     518  
     519  	// Add a few Blocks and retest after each append
     520  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     521  	assert_uint_eq(lzma_index_total_size(idx), 1000);
     522  
     523  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     524  	assert_uint_eq(lzma_index_total_size(idx), 2000);
     525  
     526  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     527  	assert_uint_eq(lzma_index_total_size(idx), 3000);
     528  
     529  	// Create second lzma_index and append Blocks to it.
     530  	lzma_index *second = lzma_index_init(NULL);
     531  	assert_true(second != NULL);
     532  
     533  	assert_uint_eq(lzma_index_total_size(second), 0);
     534  
     535  	assert_lzma_ret(lzma_index_append(second, NULL, 100, 1), LZMA_OK);
     536  	assert_uint_eq(lzma_index_total_size(second), 100);
     537  
     538  	assert_lzma_ret(lzma_index_append(second, NULL, 100, 1), LZMA_OK);
     539  	assert_uint_eq(lzma_index_total_size(second), 200);
     540  
     541  	// Concatenate the Streams together
     542  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
     543  
     544  	// The resulting total size should be the size of all Blocks
     545  	// from both Streams
     546  	assert_uint_eq(lzma_index_total_size(idx), 3200);
     547  
     548  	lzma_index_end(idx, NULL);
     549  }
     550  
     551  
     552  static void
     553  test_lzma_index_file_size(void)
     554  {
     555  	lzma_index *idx = lzma_index_init(NULL);
     556  	assert_true(idx != NULL);
     557  
     558  	// Should be the same as test_lzma_index_stream_size with
     559  	// only one Stream and no Stream Padding.
     560  	assert_uint_eq(lzma_index_file_size(idx), 32);
     561  
     562  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     563  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     564  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     565  
     566  	assert_uint_eq(lzma_index_file_size(idx), 3040);
     567  
     568  	// Next add Stream Padding
     569  	assert_lzma_ret(lzma_index_stream_padding(idx, 1000),
     570  			LZMA_OK);
     571  
     572  	assert_uint_eq(lzma_index_file_size(idx), 4040);
     573  
     574  	// Create second lzma_index.
     575  	// Very similar to test_lzma_index_stream_size, but
     576  	// the values should include the headers of the second Stream.
     577  	lzma_index *second = lzma_index_init(NULL);
     578  	assert_true(second != NULL);
     579  
     580  	assert_lzma_ret(lzma_index_append(second, NULL, 1000, 1), LZMA_OK);
     581  	assert_uint_eq(lzma_index_stream_size(second), 1036);
     582  
     583  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
     584  
     585  	// .xz file size should be:
     586  	// Size of 2 Stream Headers - 12 * 2 bytes
     587  	// Size of all Blocks - 3000 + 1000 bytes
     588  	// Size of 2 Indexes - 16 + 12 bytes
     589  	// Size of Stream Padding - 1000 bytes
     590  	// Size of 2 Stream Footers - 12 * 2 bytes
     591  	// Total: 5076 bytes
     592  	assert_uint_eq(lzma_index_file_size(idx), 5076);
     593  
     594  	lzma_index_end(idx, NULL);
     595  }
     596  
     597  
     598  static void
     599  test_lzma_index_uncompressed_size(void)
     600  {
     601  	lzma_index *idx = lzma_index_init(NULL);
     602  	assert_true(idx != NULL);
     603  
     604  	// Empty lzma_index should have 0 uncompressed .xz file size.
     605  	assert_uint_eq(lzma_index_uncompressed_size(idx), 0);
     606  
     607  	// Append a few small Blocks
     608  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
     609  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 10), LZMA_OK);
     610  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 100), LZMA_OK);
     611  
     612  	assert_uint_eq(lzma_index_uncompressed_size(idx), 111);
     613  
     614  	// Create another lzma_index
     615  	lzma_index *second = lzma_index_init(NULL);
     616  	assert_true(second != NULL);
     617  
     618  	// Append a few small Blocks
     619  	assert_lzma_ret(lzma_index_append(second, NULL, 1000, 2), LZMA_OK);
     620  	assert_lzma_ret(lzma_index_append(second, NULL, 1000, 20), LZMA_OK);
     621  	assert_lzma_ret(lzma_index_append(second, NULL, 1000, 200), LZMA_OK);
     622  
     623  	assert_uint_eq(lzma_index_uncompressed_size(second), 222);
     624  
     625  	// Concatenate second lzma_index to first
     626  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
     627  
     628  	// New uncompressed .xz file size should be the sum of the two Streams
     629  	assert_uint_eq(lzma_index_uncompressed_size(idx), 333);
     630  
     631  	// Append one more Block to the lzma_index and ensure that
     632  	// it is properly updated
     633  	assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 111), LZMA_OK);
     634  	assert_uint_eq(lzma_index_uncompressed_size(idx), 444);
     635  
     636  	lzma_index_end(idx, NULL);
     637  }
     638  
     639  
     640  static void
     641  test_lzma_index_iter_init(void)
     642  {
     643  	// Testing basic init functionality.
     644  	// The init function should call rewind on the iterator.
     645  	lzma_index *first = lzma_index_init(NULL);
     646  	assert_true(first != NULL);
     647  
     648  	lzma_index *second = lzma_index_init(NULL);
     649  	assert_true(second != NULL);
     650  
     651  	lzma_index *third = lzma_index_init(NULL);
     652  	assert_true(third != NULL);
     653  
     654  	assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK);
     655  	assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK);
     656  
     657  	lzma_index_iter iter;
     658  	lzma_index_iter_init(&iter, first);
     659  
     660  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     661  	assert_uint_eq(iter.stream.number, 1);
     662  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     663  	assert_uint_eq(iter.stream.number, 2);
     664  
     665  	lzma_index_iter_init(&iter, first);
     666  
     667  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     668  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     669  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     670  	assert_uint_eq(iter.stream.number, 3);
     671  
     672  	lzma_index_end(first, NULL);
     673  }
     674  
     675  
     676  static void
     677  test_lzma_index_iter_rewind(void)
     678  {
     679  	lzma_index *first = lzma_index_init(NULL);
     680  	assert_true(first != NULL);
     681  
     682  	lzma_index_iter iter;
     683  	lzma_index_iter_init(&iter, first);
     684  
     685  	// Append 3 Blocks and iterate over each. This is to test
     686  	// the LZMA_INDEX_ITER_BLOCK mode.
     687  	for (uint32_t i = 0; i < 3; i++) {
     688  		assert_lzma_ret(lzma_index_append(first, NULL,
     689  				UNPADDED_SIZE_MIN, 1), LZMA_OK);
     690  		assert_false(lzma_index_iter_next(&iter,
     691  				LZMA_INDEX_ITER_BLOCK));
     692  		assert_uint_eq(iter.block.number_in_file, i + 1);
     693  	}
     694  
     695  	// Rewind back to the beginning and iterate over the Blocks again
     696  	lzma_index_iter_rewind(&iter);
     697  
     698  	// Should be able to re-iterate over the Blocks again.
     699  	for (uint32_t i = 0; i < 3; i++) {
     700  		assert_false(lzma_index_iter_next(&iter,
     701  				LZMA_INDEX_ITER_BLOCK));
     702  		assert_uint_eq(iter.block.number_in_file, i + 1);
     703  	}
     704  
     705  	// Next concatenate two more lzma_indexes, iterate over them,
     706  	// rewind, and iterate over them again. This is to test
     707  	// the LZMA_INDEX_ITER_STREAM mode.
     708  	lzma_index *second = lzma_index_init(NULL);
     709  	assert_true(second != NULL);
     710  
     711  	lzma_index *third = lzma_index_init(NULL);
     712  	assert_true(third != NULL);
     713  
     714  	assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK);
     715  	assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK);
     716  
     717  	assert_false(lzma_index_iter_next(&iter,
     718  			LZMA_INDEX_ITER_STREAM));
     719  	assert_false(lzma_index_iter_next(&iter,
     720  			LZMA_INDEX_ITER_STREAM));
     721  
     722  	assert_uint_eq(iter.stream.number, 3);
     723  
     724  	lzma_index_iter_rewind(&iter);
     725  
     726  	for (uint32_t i = 0; i < 3; i++) {
     727  		assert_false(lzma_index_iter_next(&iter,
     728  				LZMA_INDEX_ITER_STREAM));
     729  		assert_uint_eq(iter.stream.number, i + 1);
     730  	}
     731  
     732  	lzma_index_end(first, NULL);
     733  }
     734  
     735  
     736  static void
     737  test_lzma_index_iter_next(void)
     738  {
     739  	lzma_index *first = lzma_index_init(NULL);
     740  	assert_true(first != NULL);
     741  
     742  	lzma_index_iter iter;
     743  	lzma_index_iter_init(&iter, first);
     744  
     745  	// First test bad mode values
     746  	for (uint32_t i = LZMA_INDEX_ITER_NONEMPTY_BLOCK + 1; i < 100; i++)
     747  		assert_true(lzma_index_iter_next(&iter, i));
     748  
     749  	// Test iterating over Blocks
     750  	assert_lzma_ret(lzma_index_append(first, NULL,
     751  			UNPADDED_SIZE_MIN, 1), LZMA_OK);
     752  	assert_lzma_ret(lzma_index_append(first, NULL,
     753  			UNPADDED_SIZE_MIN * 2, 10), LZMA_OK);
     754  	assert_lzma_ret(lzma_index_append(first, NULL,
     755  			UNPADDED_SIZE_MIN * 3, 100), LZMA_OK);
     756  
     757  	// For Blocks, need to verify:
     758  	// - number_in_file (overall Block number)
     759  	// - compressed_file_offset
     760  	// - uncompressed_file_offset
     761  	// - number_in_stream (Block number relative to current Stream)
     762  	// - compressed_stream_offset
     763  	// - uncompressed_stream_offset
     764  	// - uncompressed_size
     765  	// - unpadded_size
     766  	// - total_size
     767  
     768  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
     769  
     770  	// Verify Block data stored correctly
     771  	assert_uint_eq(iter.block.number_in_file, 1);
     772  
     773  	// Should start right after the Stream Header
     774  	assert_uint_eq(iter.block.compressed_file_offset,
     775  			LZMA_STREAM_HEADER_SIZE);
     776  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
     777  	assert_uint_eq(iter.block.number_in_stream, 1);
     778  	assert_uint_eq(iter.block.compressed_stream_offset,
     779  			LZMA_STREAM_HEADER_SIZE);
     780  	assert_uint_eq(iter.block.uncompressed_stream_offset, 0);
     781  	assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN);
     782  	assert_uint_eq(iter.block.total_size, vli_ceil4(UNPADDED_SIZE_MIN));
     783  
     784  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
     785  
     786  	// Verify Block data stored correctly
     787  	assert_uint_eq(iter.block.number_in_file, 2);
     788  	assert_uint_eq(iter.block.compressed_file_offset,
     789  			LZMA_STREAM_HEADER_SIZE +
     790  			vli_ceil4(UNPADDED_SIZE_MIN));
     791  	assert_uint_eq(iter.block.uncompressed_file_offset, 1);
     792  	assert_uint_eq(iter.block.number_in_stream, 2);
     793  	assert_uint_eq(iter.block.compressed_stream_offset,
     794  			LZMA_STREAM_HEADER_SIZE +
     795  			vli_ceil4(UNPADDED_SIZE_MIN));
     796  	assert_uint_eq(iter.block.uncompressed_stream_offset, 1);
     797  	assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN * 2);
     798  	assert_uint_eq(iter.block.total_size, vli_ceil4(UNPADDED_SIZE_MIN * 2));
     799  
     800  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
     801  
     802  	// Verify Block data stored correctly
     803  	assert_uint_eq(iter.block.number_in_file, 3);
     804  	assert_uint_eq(iter.block.compressed_file_offset,
     805  			LZMA_STREAM_HEADER_SIZE +
     806  			vli_ceil4(UNPADDED_SIZE_MIN) +
     807  			vli_ceil4(UNPADDED_SIZE_MIN * 2));
     808  	assert_uint_eq(iter.block.uncompressed_file_offset, 11);
     809  	assert_uint_eq(iter.block.number_in_stream, 3);
     810  	assert_uint_eq(iter.block.compressed_stream_offset,
     811  			LZMA_STREAM_HEADER_SIZE +
     812  			vli_ceil4(UNPADDED_SIZE_MIN) +
     813  			vli_ceil4(UNPADDED_SIZE_MIN * 2));
     814  	assert_uint_eq(iter.block.uncompressed_stream_offset, 11);
     815  	assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN * 3);
     816  	assert_uint_eq(iter.block.total_size,
     817  			vli_ceil4(UNPADDED_SIZE_MIN * 3));
     818  
     819  	// Only three Blocks were added, so this should return true
     820  	assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
     821  
     822  	const lzma_vli second_stream_compressed_start =
     823  			LZMA_STREAM_HEADER_SIZE * 2 +
     824  			vli_ceil4(UNPADDED_SIZE_MIN) +
     825  			vli_ceil4(UNPADDED_SIZE_MIN * 2) +
     826  			vli_ceil4(UNPADDED_SIZE_MIN * 3) +
     827  			lzma_index_size(first);
     828  	const lzma_vli second_stream_uncompressed_start = 1 + 10 + 100;
     829  
     830  	// Test iterating over Streams.
     831  	// The second Stream will have 0 Blocks
     832  	lzma_index *second = lzma_index_init(NULL);
     833  	assert_true(second != NULL);
     834  
     835  	// Set Stream Flags for Stream 2
     836  	lzma_stream_flags flags = {
     837  		.version = 0,
     838  		.backward_size = LZMA_BACKWARD_SIZE_MIN,
     839  		.check = LZMA_CHECK_CRC32
     840  	};
     841  
     842  	assert_lzma_ret(lzma_index_stream_flags(second, &flags), LZMA_OK);
     843  
     844  	// The Second stream will have 8 bytes of Stream Padding
     845  	assert_lzma_ret(lzma_index_stream_padding(second, 8), LZMA_OK);
     846  
     847  	const lzma_vli second_stream_index_size = lzma_index_size(second);
     848  
     849  	// The third Stream will have 2 Blocks
     850  	lzma_index *third = lzma_index_init(NULL);
     851  	assert_true(third != NULL);
     852  
     853  	assert_lzma_ret(lzma_index_append(third, NULL, 32, 20), LZMA_OK);
     854  	assert_lzma_ret(lzma_index_append(third, NULL, 64, 40), LZMA_OK);
     855  
     856  	const lzma_vli third_stream_index_size = lzma_index_size(third);
     857  
     858  	assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK);
     859  	assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK);
     860  
     861  	// For Streams, need to verify:
     862  	// - flags (Stream Flags)
     863  	// - number (Stream count)
     864  	// - block_count
     865  	// - compressed_offset
     866  	// - uncompressed_offset
     867  	// - compressed_size
     868  	// - uncompressed_size
     869  	// - padding (Stream Padding)
     870  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     871  
     872  	// Verify Stream
     873  	assert_uint_eq(iter.stream.flags->backward_size,
     874  			LZMA_BACKWARD_SIZE_MIN);
     875  	assert_uint_eq(iter.stream.flags->check, LZMA_CHECK_CRC32);
     876  	assert_uint_eq(iter.stream.number, 2);
     877  	assert_uint_eq(iter.stream.block_count, 0);
     878  	assert_uint_eq(iter.stream.compressed_offset,
     879  			second_stream_compressed_start);
     880  	assert_uint_eq(iter.stream.uncompressed_offset,
     881  			second_stream_uncompressed_start);
     882  	assert_uint_eq(iter.stream.compressed_size,
     883  			LZMA_STREAM_HEADER_SIZE * 2 +
     884  			second_stream_index_size);
     885  	assert_uint_eq(iter.stream.uncompressed_size, 0);
     886  	assert_uint_eq(iter.stream.padding, 8);
     887  
     888  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     889  
     890  	// Verify Stream
     891  	const lzma_vli third_stream_compressed_start =
     892  			second_stream_compressed_start +
     893  			LZMA_STREAM_HEADER_SIZE * 2 +
     894  			8 + // Stream padding
     895  			second_stream_index_size;
     896  	const lzma_vli third_stream_uncompressed_start =
     897  			second_stream_uncompressed_start;
     898  
     899  	assert_uint_eq(iter.stream.number, 3);
     900  	assert_uint_eq(iter.stream.block_count, 2);
     901  	assert_uint_eq(iter.stream.compressed_offset,
     902  			third_stream_compressed_start);
     903  	assert_uint_eq(iter.stream.uncompressed_offset,
     904  			third_stream_uncompressed_start);
     905  	assert_uint_eq(iter.stream.compressed_size,
     906  			LZMA_STREAM_HEADER_SIZE * 2 +
     907  			96 + // Total compressed size
     908  			third_stream_index_size);
     909  	assert_uint_eq(iter.stream.uncompressed_size, 60);
     910  	assert_uint_eq(iter.stream.padding, 0);
     911  
     912  	assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
     913  
     914  	// Even after a failing call to next with ITER_STREAM mode,
     915  	// should still be able to iterate over the 2 Blocks in
     916  	// Stream 3.
     917  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
     918  
     919  	// Verify both Blocks
     920  
     921  	// Next call to iterate Block should return true because the
     922  	// first Block can already be read from the LZMA_INDEX_ITER_STREAM
     923  	// call.
     924  	assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
     925  
     926  	// Rewind to test LZMA_INDEX_ITER_ANY
     927  	lzma_index_iter_rewind(&iter);
     928  
     929  	// Iterate past the first three Blocks
     930  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     931  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     932  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     933  
     934  	// Iterate past the next Stream
     935  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     936  
     937  	// Iterate past the next Stream
     938  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     939  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     940  
     941  	// Last call should fail
     942  	assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     943  
     944  	// Rewind to test LZMA_INDEX_ITER_NONEMPTY_BLOCK
     945  	lzma_index_iter_rewind(&iter);
     946  
     947  	// Iterate past the first three Blocks
     948  	assert_false(lzma_index_iter_next(&iter,
     949  			LZMA_INDEX_ITER_NONEMPTY_BLOCK));
     950  	assert_false(lzma_index_iter_next(&iter,
     951  			LZMA_INDEX_ITER_NONEMPTY_BLOCK));
     952  	assert_false(lzma_index_iter_next(&iter,
     953  			LZMA_INDEX_ITER_NONEMPTY_BLOCK));
     954  
     955  	// Skip past the next Stream which has no Blocks.
     956  	// We will get to the first Block of the third Stream.
     957  	assert_false(lzma_index_iter_next(&iter,
     958  			LZMA_INDEX_ITER_NONEMPTY_BLOCK));
     959  
     960  	// Iterate past the second (the last) Block in the third Stream
     961  	assert_false(lzma_index_iter_next(&iter,
     962  			LZMA_INDEX_ITER_NONEMPTY_BLOCK));
     963  
     964  	// Last call should fail since there is nothing left to iterate over.
     965  	assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
     966  
     967  	lzma_index_end(first, NULL);
     968  }
     969  
     970  
     971  static void
     972  test_lzma_index_iter_locate(void)
     973  {
     974  	lzma_index *idx = lzma_index_init(NULL);
     975  	assert_true(idx != NULL);
     976  
     977  	lzma_index_iter iter;
     978  	lzma_index_iter_init(&iter, idx);
     979  
     980  	// Cannot locate anything from an empty Index.
     981  	assert_true(lzma_index_iter_locate(&iter, 0));
     982  	assert_true(lzma_index_iter_locate(&iter, 555));
     983  
     984  	// One empty Record: nothing is found since there's no uncompressed
     985  	// data.
     986  	assert_lzma_ret(lzma_index_append(idx, NULL, 16, 0), LZMA_OK);
     987  	assert_true(lzma_index_iter_locate(&iter, 0));
     988  
     989  	// Non-empty Record and we can find something.
     990  	assert_lzma_ret(lzma_index_append(idx, NULL, 32, 5), LZMA_OK);
     991  	assert_false(lzma_index_iter_locate(&iter, 0));
     992  	assert_uint_eq(iter.block.total_size, 32);
     993  	assert_uint_eq(iter.block.uncompressed_size, 5);
     994  	assert_uint_eq(iter.block.compressed_file_offset,
     995  			LZMA_STREAM_HEADER_SIZE + 16);
     996  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
     997  
     998  	// Still cannot find anything past the end.
     999  	assert_true(lzma_index_iter_locate(&iter, 5));
    1000  
    1001  	// Add the third Record.
    1002  	assert_lzma_ret(lzma_index_append(idx, NULL, 40, 11), LZMA_OK);
    1003  
    1004  	assert_false(lzma_index_iter_locate(&iter, 0));
    1005  	assert_uint_eq(iter.block.total_size, 32);
    1006  	assert_uint_eq(iter.block.uncompressed_size, 5);
    1007  	assert_uint_eq(iter.block.compressed_file_offset,
    1008  			LZMA_STREAM_HEADER_SIZE + 16);
    1009  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
    1010  
    1011  	assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
    1012  	assert_uint_eq(iter.block.total_size, 40);
    1013  	assert_uint_eq(iter.block.uncompressed_size, 11);
    1014  	assert_uint_eq(iter.block.compressed_file_offset,
    1015  			LZMA_STREAM_HEADER_SIZE + 16 + 32);
    1016  	assert_uint_eq(iter.block.uncompressed_file_offset, 5);
    1017  
    1018  	assert_false(lzma_index_iter_locate(&iter, 2));
    1019  	assert_uint_eq(iter.block.total_size, 32);
    1020  	assert_uint_eq(iter.block.uncompressed_size, 5);
    1021  	assert_uint_eq(iter.block.compressed_file_offset,
    1022  			LZMA_STREAM_HEADER_SIZE + 16);
    1023  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
    1024  
    1025  	assert_false(lzma_index_iter_locate(&iter, 5));
    1026  	assert_uint_eq(iter.block.total_size, 40);
    1027  	assert_uint_eq(iter.block.uncompressed_size, 11);
    1028  	assert_uint_eq(iter.block.compressed_file_offset,
    1029  			LZMA_STREAM_HEADER_SIZE + 16 + 32);
    1030  	assert_uint_eq(iter.block.uncompressed_file_offset, 5);
    1031  
    1032  	assert_false(lzma_index_iter_locate(&iter, 5 + 11 - 1));
    1033  	assert_uint_eq(iter.block.total_size, 40);
    1034  	assert_uint_eq(iter.block.uncompressed_size, 11);
    1035  	assert_uint_eq(iter.block.compressed_file_offset,
    1036  			LZMA_STREAM_HEADER_SIZE + 16 + 32);
    1037  	assert_uint_eq(iter.block.uncompressed_file_offset, 5);
    1038  
    1039  	assert_true(lzma_index_iter_locate(&iter, 5 + 11));
    1040  	assert_true(lzma_index_iter_locate(&iter, 5 + 15));
    1041  
    1042  	// Large Index
    1043  	lzma_index_end(idx, NULL);
    1044  	idx = lzma_index_init(NULL);
    1045  	assert_true(idx != NULL);
    1046  	lzma_index_iter_init(&iter, idx);
    1047  
    1048  	for (uint32_t n = 4; n <= 4 * 5555; n += 4)
    1049  		assert_lzma_ret(lzma_index_append(idx, NULL, n + 8, n),
    1050  				LZMA_OK);
    1051  
    1052  	assert_uint_eq(lzma_index_block_count(idx), 5555);
    1053  
    1054  	// First Record
    1055  	assert_false(lzma_index_iter_locate(&iter, 0));
    1056  	assert_uint_eq(iter.block.total_size, 4 + 8);
    1057  	assert_uint_eq(iter.block.uncompressed_size, 4);
    1058  	assert_uint_eq(iter.block.compressed_file_offset,
    1059  			LZMA_STREAM_HEADER_SIZE);
    1060  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
    1061  
    1062  	assert_false(lzma_index_iter_locate(&iter, 3));
    1063  	assert_uint_eq(iter.block.total_size, 4 + 8);
    1064  	assert_uint_eq(iter.block.uncompressed_size, 4);
    1065  	assert_uint_eq(iter.block.compressed_file_offset,
    1066  			LZMA_STREAM_HEADER_SIZE);
    1067  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
    1068  
    1069  	// Second Record
    1070  	assert_false(lzma_index_iter_locate(&iter, 4));
    1071  	assert_uint_eq(iter.block.total_size, 2 * 4 + 8);
    1072  	assert_uint_eq(iter.block.uncompressed_size, 2 * 4);
    1073  	assert_uint_eq(iter.block.compressed_file_offset,
    1074  			LZMA_STREAM_HEADER_SIZE + 4 + 8);
    1075  	assert_uint_eq(iter.block.uncompressed_file_offset, 4);
    1076  
    1077  	// Last Record
    1078  	assert_false(lzma_index_iter_locate(
    1079  			&iter, lzma_index_uncompressed_size(idx) - 1));
    1080  	assert_uint_eq(iter.block.total_size, 4 * 5555 + 8);
    1081  	assert_uint_eq(iter.block.uncompressed_size, 4 * 5555);
    1082  	assert_uint_eq(iter.block.compressed_file_offset,
    1083  			lzma_index_total_size(idx)
    1084  			+ LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
    1085  	assert_uint_eq(iter.block.uncompressed_file_offset,
    1086  			lzma_index_uncompressed_size(idx) - 4 * 5555);
    1087  
    1088  	// Allocation chunk boundaries. See INDEX_GROUP_SIZE in
    1089  	// liblzma/common/index.c.
    1090  	const uint32_t group_multiple = 256 * 4;
    1091  	const uint32_t radius = 8;
    1092  	const uint32_t start = group_multiple - radius;
    1093  	lzma_vli ubase = 0;
    1094  	lzma_vli tbase = 0;
    1095  	uint32_t n;
    1096  	for (n = 1; n < start; ++n) {
    1097  		ubase += n * 4;
    1098  		tbase += n * 4 + 8;
    1099  	}
    1100  
    1101  	while (n < start + 2 * radius) {
    1102  		assert_false(lzma_index_iter_locate(&iter, ubase + n * 4));
    1103  
    1104  		assert_uint_eq(iter.block.compressed_file_offset,
    1105  				tbase + n * 4 + 8
    1106  				+ LZMA_STREAM_HEADER_SIZE);
    1107  		assert_uint_eq(iter.block.uncompressed_file_offset,
    1108  				ubase + n * 4);
    1109  
    1110  		tbase += n * 4 + 8;
    1111  		ubase += n * 4;
    1112  		++n;
    1113  
    1114  		assert_uint_eq(iter.block.total_size, n * 4 + 8);
    1115  		assert_uint_eq(iter.block.uncompressed_size, n * 4);
    1116  	}
    1117  
    1118  	// Do it also backwards.
    1119  	while (n > start) {
    1120  		assert_false(lzma_index_iter_locate(
    1121  				&iter, ubase + (n - 1) * 4));
    1122  
    1123  		assert_uint_eq(iter.block.total_size, n * 4 + 8);
    1124  		assert_uint_eq(iter.block.uncompressed_size, n * 4);
    1125  
    1126  		--n;
    1127  		tbase -= n * 4 + 8;
    1128  		ubase -= n * 4;
    1129  
    1130  		assert_uint_eq(iter.block.compressed_file_offset,
    1131  				tbase + n * 4 + 8
    1132  				+ LZMA_STREAM_HEADER_SIZE);
    1133  		assert_uint_eq(iter.block.uncompressed_file_offset,
    1134  				ubase + n * 4);
    1135  	}
    1136  
    1137  	// Test locating in concatenated Index.
    1138  	lzma_index_end(idx, NULL);
    1139  	idx = lzma_index_init(NULL);
    1140  	assert_true(idx != NULL);
    1141  	lzma_index_iter_init(&iter, idx);
    1142  	for (n = 0; n < group_multiple; ++n)
    1143  		assert_lzma_ret(lzma_index_append(idx, NULL, 8, 0),
    1144  				LZMA_OK);
    1145  	assert_lzma_ret(lzma_index_append(idx, NULL, 16, 1), LZMA_OK);
    1146  	assert_false(lzma_index_iter_locate(&iter, 0));
    1147  	assert_uint_eq(iter.block.total_size, 16);
    1148  	assert_uint_eq(iter.block.uncompressed_size, 1);
    1149  	assert_uint_eq(iter.block.compressed_file_offset,
    1150  			LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
    1151  	assert_uint_eq(iter.block.uncompressed_file_offset, 0);
    1152  
    1153  	lzma_index_end(idx, NULL);
    1154  }
    1155  
    1156  
    1157  static void
    1158  test_lzma_index_cat(void)
    1159  {
    1160  	// Most complex tests for this function are done in other tests.
    1161  	// This will mostly test basic functionality.
    1162  
    1163  	lzma_index *dest = lzma_index_init(NULL);
    1164  	assert_true(dest != NULL);
    1165  
    1166  	lzma_index *src = lzma_index_init(NULL);
    1167  	assert_true(src != NULL);
    1168  
    1169  	// First test NULL dest or src
    1170  	assert_lzma_ret(lzma_index_cat(NULL, NULL, NULL), LZMA_PROG_ERROR);
    1171  	assert_lzma_ret(lzma_index_cat(dest, NULL, NULL), LZMA_PROG_ERROR);
    1172  	assert_lzma_ret(lzma_index_cat(NULL, src, NULL), LZMA_PROG_ERROR);
    1173  
    1174  	// Check for uncompressed size overflow
    1175  	assert_lzma_ret(lzma_index_append(dest, NULL,
    1176  			(UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK);
    1177  	assert_lzma_ret(lzma_index_append(src, NULL,
    1178  			(UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK);
    1179  	assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR);
    1180  
    1181  	// Check for compressed size overflow
    1182  	lzma_index_end(src, NULL);
    1183  	lzma_index_end(dest, NULL);
    1184  
    1185  	dest = lzma_index_init(NULL);
    1186  	assert_true(dest != NULL);
    1187  
    1188  	src = lzma_index_init(NULL);
    1189  	assert_true(src != NULL);
    1190  
    1191  	assert_lzma_ret(lzma_index_append(dest, NULL,
    1192  			UNPADDED_SIZE_MIN, LZMA_VLI_MAX - 1), LZMA_OK);
    1193  	assert_lzma_ret(lzma_index_append(src, NULL,
    1194  			UNPADDED_SIZE_MIN, LZMA_VLI_MAX - 1), LZMA_OK);
    1195  	assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR);
    1196  
    1197  	lzma_index_end(dest, NULL);
    1198  	lzma_index_end(src, NULL);
    1199  }
    1200  
    1201  
    1202  // Helper function for test_lzma_index_dup().
    1203  static bool
    1204  index_is_equal(const lzma_index *a, const lzma_index *b)
    1205  {
    1206  	// Compare only the Stream and Block sizes and offsets.
    1207  	lzma_index_iter ra, rb;
    1208  	lzma_index_iter_init(&ra, a);
    1209  	lzma_index_iter_init(&rb, b);
    1210  
    1211  	while (true) {
    1212  		bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY);
    1213  		bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY);
    1214  
    1215  		// If both iterators finish at the same time, then the Indexes
    1216  		// are identical.
    1217  		if (reta)
    1218  			return retb;
    1219  
    1220  		if (ra.stream.number != rb.stream.number
    1221  				|| ra.stream.block_count
    1222  					!= rb.stream.block_count
    1223  				|| ra.stream.compressed_offset
    1224  					!= rb.stream.compressed_offset
    1225  				|| ra.stream.uncompressed_offset
    1226  					!= rb.stream.uncompressed_offset
    1227  				|| ra.stream.compressed_size
    1228  					!= rb.stream.compressed_size
    1229  				|| ra.stream.uncompressed_size
    1230  					!= rb.stream.uncompressed_size
    1231  				|| ra.stream.padding
    1232  					!= rb.stream.padding)
    1233  			return false;
    1234  
    1235  		if (ra.stream.block_count == 0)
    1236  			continue;
    1237  
    1238  		if (ra.block.number_in_file != rb.block.number_in_file
    1239  				|| ra.block.compressed_file_offset
    1240  					!= rb.block.compressed_file_offset
    1241  				|| ra.block.uncompressed_file_offset
    1242  					!= rb.block.uncompressed_file_offset
    1243  				|| ra.block.number_in_stream
    1244  					!= rb.block.number_in_stream
    1245  				|| ra.block.compressed_stream_offset
    1246  					!= rb.block.compressed_stream_offset
    1247  				|| ra.block.uncompressed_stream_offset
    1248  					!= rb.block.uncompressed_stream_offset
    1249  				|| ra.block.uncompressed_size
    1250  					!= rb.block.uncompressed_size
    1251  				|| ra.block.unpadded_size
    1252  					!= rb.block.unpadded_size
    1253  				|| ra.block.total_size
    1254  					!= rb.block.total_size)
    1255  			return false;
    1256  	}
    1257  }
    1258  
    1259  
    1260  // Allocator that succeeds for the first two allocation but fails the rest.
    1261  static void *
    1262  my_alloc(void *opaque, size_t a, size_t b)
    1263  {
    1264  	(void)opaque;
    1265  
    1266  	static unsigned count = 0;
    1267  	if (++count > 2)
    1268  		return NULL;
    1269  
    1270  	return malloc(a * b);
    1271  }
    1272  
    1273  static const lzma_allocator test_index_dup_alloc = { &my_alloc, NULL, NULL };
    1274  
    1275  
    1276  static void
    1277  test_lzma_index_dup(void)
    1278  {
    1279  	lzma_index *idx = lzma_index_init(NULL);
    1280  	assert_true(idx != NULL);
    1281  
    1282  	// Test for the bug fix 21515d79d778b8730a434f151b07202d52a04611:
    1283  	// liblzma: Fix lzma_index_dup() for empty Streams.
    1284  	assert_lzma_ret(lzma_index_stream_padding(idx, 4), LZMA_OK);
    1285  	lzma_index *copy = lzma_index_dup(idx, NULL);
    1286  	assert_true(copy != NULL);
    1287  	assert_true(index_is_equal(idx, copy));
    1288  	lzma_index_end(copy, NULL);
    1289  
    1290  	// Test for the bug fix 3bf857edfef51374f6f3fffae3d817f57d3264a0:
    1291  	// liblzma: Fix a memory leak in error path of lzma_index_dup().
    1292  	// Use Valgrind to see that there are no leaks.
    1293  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1294  			UNPADDED_SIZE_MIN, 10), LZMA_OK);
    1295  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1296  			UNPADDED_SIZE_MIN * 2, 100), LZMA_OK);
    1297  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1298  			UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK);
    1299  
    1300  	assert_true(lzma_index_dup(idx, &test_index_dup_alloc) == NULL);
    1301  
    1302  	// Test a few streams and blocks
    1303  	lzma_index *second = lzma_index_init(NULL);
    1304  	assert_true(second != NULL);
    1305  
    1306  	assert_lzma_ret(lzma_index_stream_padding(second, 16), LZMA_OK);
    1307  
    1308  	lzma_index *third = lzma_index_init(NULL);
    1309  	assert_true(third != NULL);
    1310  
    1311  	assert_lzma_ret(lzma_index_append(third, NULL,
    1312  			UNPADDED_SIZE_MIN * 10, 40), LZMA_OK);
    1313  	assert_lzma_ret(lzma_index_append(third, NULL,
    1314  			UNPADDED_SIZE_MIN * 20, 400), LZMA_OK);
    1315  	assert_lzma_ret(lzma_index_append(third, NULL,
    1316  			UNPADDED_SIZE_MIN * 30, 4000), LZMA_OK);
    1317  
    1318  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
    1319  	assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK);
    1320  
    1321  	copy = lzma_index_dup(idx, NULL);
    1322  	assert_true(copy != NULL);
    1323  	assert_true(index_is_equal(idx, copy));
    1324  
    1325  	lzma_index_end(copy, NULL);
    1326  	lzma_index_end(idx, NULL);
    1327  }
    1328  
    1329  #if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
    1330  static void
    1331  verify_index_buffer(const lzma_index *idx, const uint8_t *buffer,
    1332  		const size_t buffer_size)
    1333  {
    1334  	lzma_index_iter iter;
    1335  	lzma_index_iter_init(&iter, idx);
    1336  
    1337  	size_t buffer_pos = 0;
    1338  
    1339  	// Verify Index Indicator
    1340  	assert_uint_eq(buffer[buffer_pos++], 0);
    1341  
    1342  	// Get Number of Records
    1343  	lzma_vli number_of_records = 0;
    1344  	lzma_vli block_count = 0;
    1345  	assert_lzma_ret(lzma_vli_decode(&number_of_records, NULL, buffer,
    1346  			&buffer_pos, buffer_size), LZMA_OK);
    1347  
    1348  	while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)) {
    1349  		// Verify each Record (Unpadded Size, then Uncompressed Size).
    1350  		// Verify Unpadded Size.
    1351  		lzma_vli unpadded_size, uncompressed_size;
    1352  		assert_lzma_ret(lzma_vli_decode(&unpadded_size,
    1353  				NULL, buffer, &buffer_pos,
    1354  				buffer_size), LZMA_OK);
    1355  		assert_uint_eq(unpadded_size,
    1356  				iter.block.unpadded_size);
    1357  
    1358  		// Verify Uncompressed Size
    1359  		assert_lzma_ret(lzma_vli_decode(&uncompressed_size,
    1360  				NULL, buffer, &buffer_pos,
    1361  				buffer_size), LZMA_OK);
    1362  		assert_uint_eq(uncompressed_size,
    1363  				iter.block.uncompressed_size);
    1364  
    1365  		block_count++;
    1366  	}
    1367  
    1368  	// Verify Number of Records
    1369  	assert_uint_eq(number_of_records, block_count);
    1370  
    1371  	// Verify Index Padding
    1372  	for (; buffer_pos % 4 != 0; buffer_pos++)
    1373  		assert_uint_eq(buffer[buffer_pos], 0);
    1374  
    1375  	// Verify CRC32
    1376  	uint32_t crc32 = lzma_crc32(buffer, buffer_pos, 0);
    1377  	assert_uint_eq(read32le(buffer + buffer_pos), crc32);
    1378  }
    1379  
    1380  
    1381  // In a few places the Index size is needed as a size_t but lzma_index_size()
    1382  // returns lzma_vli.
    1383  static size_t
    1384  get_index_size(const lzma_index *idx)
    1385  {
    1386  	const lzma_vli size = lzma_index_size(idx);
    1387  	assert_uint(size, <, SIZE_MAX);
    1388  	return (size_t)size;
    1389  }
    1390  #endif
    1391  
    1392  
    1393  static void
    1394  test_lzma_index_encoder(void)
    1395  {
    1396  #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
    1397  	assert_skip("Encoder or decoder support disabled");
    1398  #else
    1399  	lzma_index *idx = lzma_index_init(NULL);
    1400  	assert_true(idx != NULL);
    1401  
    1402  	lzma_stream strm = LZMA_STREAM_INIT;
    1403  
    1404  	// First do basic NULL checks
    1405  	assert_lzma_ret(lzma_index_encoder(NULL, NULL), LZMA_PROG_ERROR);
    1406  	assert_lzma_ret(lzma_index_encoder(&strm, NULL), LZMA_PROG_ERROR);
    1407  	assert_lzma_ret(lzma_index_encoder(NULL, idx), LZMA_PROG_ERROR);
    1408  
    1409  	// Append three small Blocks
    1410  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1411  			UNPADDED_SIZE_MIN, 10), LZMA_OK);
    1412  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1413  			UNPADDED_SIZE_MIN * 2, 100), LZMA_OK);
    1414  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1415  			UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK);
    1416  
    1417  	// Encode this lzma_index into a buffer
    1418  	size_t buffer_size = get_index_size(idx);
    1419  	uint8_t *buffer = tuktest_malloc(buffer_size);
    1420  
    1421  	assert_lzma_ret(lzma_index_encoder(&strm, idx), LZMA_OK);
    1422  
    1423  	strm.avail_out = buffer_size;
    1424  	strm.next_out = buffer;
    1425  
    1426  	assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
    1427  	assert_uint_eq(strm.avail_out, 0);
    1428  
    1429  	lzma_end(&strm);
    1430  
    1431  	verify_index_buffer(idx, buffer, buffer_size);
    1432  
    1433  	// Test with multiple Streams concatenated into 1 Index
    1434  	lzma_index *second = lzma_index_init(NULL);
    1435  	assert_true(second != NULL);
    1436  
    1437  	// Include 1 Block
    1438  	assert_lzma_ret(lzma_index_append(second, NULL,
    1439  			UNPADDED_SIZE_MIN * 4, 20), LZMA_OK);
    1440  
    1441  	// Include Stream Padding
    1442  	assert_lzma_ret(lzma_index_stream_padding(second, 16), LZMA_OK);
    1443  
    1444  	assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
    1445  	buffer_size = get_index_size(idx);
    1446  	buffer = tuktest_malloc(buffer_size);
    1447  	assert_lzma_ret(lzma_index_encoder(&strm, idx), LZMA_OK);
    1448  
    1449  	strm.avail_out = buffer_size;
    1450  	strm.next_out = buffer;
    1451  
    1452  	assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
    1453  	assert_uint_eq(strm.avail_out, 0);
    1454  
    1455  	verify_index_buffer(idx, buffer, buffer_size);
    1456  
    1457  	lzma_index_end(idx, NULL);
    1458  	lzma_end(&strm);
    1459  #endif
    1460  }
    1461  
    1462  static void
    1463  generate_index_decode_buffer(void)
    1464  {
    1465  #ifdef HAVE_ENCODERS
    1466  	decode_test_index = lzma_index_init(NULL);
    1467  	if (decode_test_index == NULL)
    1468  		return;
    1469  
    1470  	// Add 4 Blocks
    1471  	for (uint32_t i = 1; i < 5; i++)
    1472  		if (lzma_index_append(decode_test_index, NULL,
    1473  				0x1000 * i, 0x100 * i) != LZMA_OK)
    1474  			return;
    1475  
    1476  	size_t size = lzma_index_size(decode_test_index);
    1477  	decode_buffer = tuktest_malloc(size);
    1478  
    1479  	if (lzma_index_buffer_encode(decode_test_index,
    1480  			decode_buffer, &decode_buffer_size, size) != LZMA_OK)
    1481  		decode_buffer_size = 0;
    1482  #endif
    1483  }
    1484  
    1485  
    1486  #ifdef HAVE_DECODERS
    1487  static void
    1488  decode_index(const uint8_t *buffer, const size_t size, lzma_stream *strm,
    1489  		lzma_ret expected_error)
    1490  {
    1491  	strm->avail_in = size;
    1492  	strm->next_in = buffer;
    1493  	assert_lzma_ret(lzma_code(strm, LZMA_FINISH), expected_error);
    1494  }
    1495  #endif
    1496  
    1497  
    1498  static void
    1499  test_lzma_index_decoder(void)
    1500  {
    1501  #ifndef HAVE_DECODERS
    1502  	assert_skip("Decoder support disabled");
    1503  #else
    1504  	if (decode_buffer_size == 0)
    1505  		assert_skip("Could not initialize decode test buffer");
    1506  
    1507  	lzma_stream strm = LZMA_STREAM_INIT;
    1508  
    1509  	assert_lzma_ret(lzma_index_decoder(NULL, NULL, MEMLIMIT),
    1510  			LZMA_PROG_ERROR);
    1511  	assert_lzma_ret(lzma_index_decoder(&strm, NULL, MEMLIMIT),
    1512  			LZMA_PROG_ERROR);
    1513  	assert_lzma_ret(lzma_index_decoder(NULL, &decode_test_index,
    1514  			MEMLIMIT), LZMA_PROG_ERROR);
    1515  
    1516  	// Do actual decode
    1517  	lzma_index *idx;
    1518  	assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
    1519  			LZMA_OK);
    1520  
    1521  	decode_index(decode_buffer, decode_buffer_size, &strm,
    1522  			LZMA_STREAM_END);
    1523  
    1524  	// Compare results with expected
    1525  	assert_true(index_is_equal(decode_test_index, idx));
    1526  
    1527  	lzma_index_end(idx, NULL);
    1528  
    1529  	// Test again with too low memory limit
    1530  	assert_lzma_ret(lzma_index_decoder(&strm, &idx, 0), LZMA_OK);
    1531  
    1532  	decode_index(decode_buffer, decode_buffer_size, &strm,
    1533  			LZMA_MEMLIMIT_ERROR);
    1534  
    1535  	uint8_t *corrupt_buffer = tuktest_malloc(decode_buffer_size);
    1536  	memcpy(corrupt_buffer, decode_buffer, decode_buffer_size);
    1537  
    1538  	assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
    1539  			LZMA_OK);
    1540  
    1541  	// First corrupt the Index Indicator
    1542  	corrupt_buffer[0] ^= 1;
    1543  	decode_index(corrupt_buffer, decode_buffer_size, &strm,
    1544  			LZMA_DATA_ERROR);
    1545  	corrupt_buffer[0] ^= 1;
    1546  
    1547  	// Corrupt something in the middle of Index
    1548  	corrupt_buffer[decode_buffer_size / 2] ^= 1;
    1549  	assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
    1550  			LZMA_OK);
    1551  	decode_index(corrupt_buffer, decode_buffer_size, &strm,
    1552  			LZMA_DATA_ERROR);
    1553  	corrupt_buffer[decode_buffer_size / 2] ^= 1;
    1554  
    1555  	// Corrupt CRC32
    1556  	corrupt_buffer[decode_buffer_size - 1] ^= 1;
    1557  	assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
    1558  			LZMA_OK);
    1559  	decode_index(corrupt_buffer, decode_buffer_size, &strm,
    1560  			LZMA_DATA_ERROR);
    1561  	corrupt_buffer[decode_buffer_size - 1] ^= 1;
    1562  
    1563  	// Corrupt Index Padding by setting it to non-zero
    1564  	corrupt_buffer[decode_buffer_size - 5] ^= 1;
    1565  	assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
    1566  			LZMA_OK);
    1567  	decode_index(corrupt_buffer, decode_buffer_size, &strm,
    1568  			LZMA_DATA_ERROR);
    1569  	corrupt_buffer[decode_buffer_size - 1] ^= 1;
    1570  
    1571  	lzma_end(&strm);
    1572  #endif
    1573  }
    1574  
    1575  
    1576  static void
    1577  test_lzma_index_buffer_encode(void)
    1578  {
    1579  #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
    1580  	assert_skip("Encoder or decoder support disabled");
    1581  #else
    1582  	// More simple test than test_lzma_index_encoder() because
    1583  	// currently lzma_index_buffer_encode() is mostly a wrapper
    1584  	// around lzma_index_encoder() anyway.
    1585  	lzma_index *idx = lzma_index_init(NULL);
    1586  	assert_true(idx != NULL);
    1587  
    1588  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1589  			UNPADDED_SIZE_MIN, 10), LZMA_OK);
    1590  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1591  			UNPADDED_SIZE_MIN * 2, 100), LZMA_OK);
    1592  	assert_lzma_ret(lzma_index_append(idx, NULL,
    1593  			UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK);
    1594  
    1595  	size_t buffer_size = get_index_size(idx);
    1596  	uint8_t *buffer = tuktest_malloc(buffer_size);
    1597  	size_t out_pos = 1;
    1598  
    1599  	// First test bad arguments
    1600  	assert_lzma_ret(lzma_index_buffer_encode(NULL, NULL, NULL, 0),
    1601  			LZMA_PROG_ERROR);
    1602  	assert_lzma_ret(lzma_index_buffer_encode(idx, NULL, NULL, 0),
    1603  			LZMA_PROG_ERROR);
    1604  	assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, NULL, 0),
    1605  			LZMA_PROG_ERROR);
    1606  	assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
    1607  			0), LZMA_PROG_ERROR);
    1608  	out_pos = 0;
    1609  	assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
    1610  			1), LZMA_BUF_ERROR);
    1611  
    1612  	// Do encoding
    1613  	assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
    1614  			buffer_size), LZMA_OK);
    1615  	assert_uint_eq(out_pos, buffer_size);
    1616  
    1617  	// Validate results
    1618  	verify_index_buffer(idx, buffer, buffer_size);
    1619  
    1620  	lzma_index_end(idx, NULL);
    1621  #endif
    1622  }
    1623  
    1624  
    1625  static void
    1626  test_lzma_index_buffer_decode(void)
    1627  {
    1628  #ifndef HAVE_DECODERS
    1629  	assert_skip("Decoder support disabled");
    1630  #else
    1631  	if (decode_buffer_size == 0)
    1632  		assert_skip("Could not initialize decode test buffer");
    1633  
    1634  	// Simple test since test_lzma_index_decoder() covers most of the
    1635  	// lzma_index_buffer_decode() code anyway.
    1636  
    1637  	// First test NULL checks
    1638  	assert_lzma_ret(lzma_index_buffer_decode(NULL, NULL, NULL, NULL,
    1639  			NULL, 0), LZMA_PROG_ERROR);
    1640  
    1641  	lzma_index *idx;
    1642  	uint64_t memlimit = MEMLIMIT;
    1643  	size_t in_pos = 0;
    1644  
    1645  	assert_lzma_ret(lzma_index_buffer_decode(&idx, NULL, NULL, NULL,
    1646  			NULL, 0), LZMA_PROG_ERROR);
    1647  
    1648  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1649  			NULL, NULL, 0), LZMA_PROG_ERROR);
    1650  
    1651  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1652  			decode_buffer, NULL, 0), LZMA_PROG_ERROR);
    1653  
    1654  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1655  			decode_buffer, NULL, 0), LZMA_PROG_ERROR);
    1656  
    1657  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1658  			decode_buffer, &in_pos, 0), LZMA_DATA_ERROR);
    1659  
    1660  	in_pos = 1;
    1661  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1662  			decode_buffer, &in_pos, 0), LZMA_PROG_ERROR);
    1663  	in_pos = 0;
    1664  
    1665  	// Test expected successful decode
    1666  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1667  			decode_buffer, &in_pos, decode_buffer_size), LZMA_OK);
    1668  
    1669  	assert_true(index_is_equal(decode_test_index, idx));
    1670  
    1671  	lzma_index_end(idx, NULL);
    1672  
    1673  	// Test too small memlimit
    1674  	in_pos = 0;
    1675  	memlimit = 1;
    1676  	assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
    1677  			decode_buffer, &in_pos, decode_buffer_size),
    1678  			LZMA_MEMLIMIT_ERROR);
    1679  	assert_uint(memlimit, >, 1);
    1680  	assert_uint(memlimit, <, MEMLIMIT);
    1681  #endif
    1682  }
    1683  
    1684  
    1685  extern int
    1686  main(int argc, char **argv)
    1687  {
    1688  	tuktest_start(argc, argv);
    1689  	generate_index_decode_buffer();
    1690  	tuktest_run(test_lzma_index_memusage);
    1691  	tuktest_run(test_lzma_index_memused);
    1692  	tuktest_run(test_lzma_index_append);
    1693  	tuktest_run(test_lzma_index_stream_flags);
    1694  	tuktest_run(test_lzma_index_checks);
    1695  	tuktest_run(test_lzma_index_stream_padding);
    1696  	tuktest_run(test_lzma_index_stream_count);
    1697  	tuktest_run(test_lzma_index_block_count);
    1698  	tuktest_run(test_lzma_index_size);
    1699  	tuktest_run(test_lzma_index_stream_size);
    1700  	tuktest_run(test_lzma_index_total_size);
    1701  	tuktest_run(test_lzma_index_file_size);
    1702  	tuktest_run(test_lzma_index_uncompressed_size);
    1703  	tuktest_run(test_lzma_index_iter_init);
    1704  	tuktest_run(test_lzma_index_iter_rewind);
    1705  	tuktest_run(test_lzma_index_iter_next);
    1706  	tuktest_run(test_lzma_index_iter_locate);
    1707  	tuktest_run(test_lzma_index_cat);
    1708  	tuktest_run(test_lzma_index_dup);
    1709  	tuktest_run(test_lzma_index_encoder);
    1710  	tuktest_run(test_lzma_index_decoder);
    1711  	tuktest_run(test_lzma_index_buffer_encode);
    1712  	tuktest_run(test_lzma_index_buffer_decode);
    1713  	lzma_index_end(decode_test_index, NULL);
    1714  	return tuktest_end();
    1715  }