Home | History | Annotate | Line # | Download | only in tests
      1 // SPDX-License-Identifier: 0BSD
      2 
      3 ///////////////////////////////////////////////////////////////////////////////
      4 //
      5 /// \file       test_vli.c
      6 /// \brief      Tests liblzma vli functions
      7 //
      8 //  Author:     Jia Tan
      9 //
     10 ///////////////////////////////////////////////////////////////////////////////
     11 
     12 #include "tests.h"
     13 
     14 
     15 // Pre-encoded VLI values for testing
     16 // VLI can have between 1 and 9 bytes when encoded
     17 // They are encoded little endian where all but the last
     18 // byte must have the leading 1 bit set
     19 #if defined(HAVE_ENCODERS) || defined(HAVE_DECODERS)
     20 static const uint8_t one_byte[1] = {0x25};
     21 static const lzma_vli one_byte_value = 37;
     22 
     23 static const uint8_t two_bytes[2] = {0x80, 0x56};
     24 static const lzma_vli two_byte_value = 11008;
     25 
     26 static const uint8_t three_bytes[3] = {0x99, 0x92, 0x20};
     27 static const lzma_vli three_byte_value = 526617;
     28 
     29 static const uint8_t four_bytes[4] = {0x97, 0x83, 0x94, 0x47};
     30 static const lzma_vli four_byte_value = 149225879;
     31 
     32 static const uint8_t five_bytes[5] = {0xA6, 0x92, 0x88, 0x89, 0x32};
     33 static const lzma_vli five_byte_value = 13440780582;
     34 
     35 static const uint8_t six_bytes[6] = {0xA9, 0x84, 0x99, 0x82, 0x94, 0x12};
     36 static const lzma_vli six_byte_value = 623848604201;
     37 
     38 static const uint8_t seven_bytes[7] = {0x90, 0x80, 0x90, 0x80, 0x90, 0x80,
     39 				0x79};
     40 static const lzma_vli seven_byte_value = 532167923073040;
     41 
     42 static const uint8_t eight_bytes[8] = {0x91, 0x87, 0xF2, 0xB2, 0xC2, 0xD2,
     43 				0x93, 0x63};
     44 static const lzma_vli eight_byte_value = 55818443594433425;
     45 
     46 static const uint8_t nine_bytes[9] = {0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1,
     47 				0xE1, 0xF1, 0x1};
     48 static const lzma_vli nine_byte_value = 136100349976529025;
     49 #endif
     50 
     51 
     52 static void
     53 test_lzma_vli_size(void)
     54 {
     55 	// First test invalid VLI values (should return 0)
     56 	// VLI UNKNOWN is an invalid VLI
     57 	assert_uint_eq(lzma_vli_size(LZMA_VLI_UNKNOWN), 0);
     58 	// Loop over a few VLI values just over the maximum
     59 	for (uint64_t i = LZMA_VLI_MAX + 1; i < LZMA_VLI_MAX + 10; i++)
     60 		assert_uint_eq(lzma_vli_size(i), 0);
     61 
     62 	// Number should increment every seven set bits
     63 	lzma_vli vli = 1;
     64 	for (uint32_t i = 1; i < LZMA_VLI_BYTES_MAX; i++, vli <<= 7) {
     65 		// Test the base value and a few others around it
     66 		assert_uint_eq(lzma_vli_size(vli), i);
     67 		assert_uint_eq(lzma_vli_size(vli * 2), i);
     68 		assert_uint_eq(lzma_vli_size(vli + 10), i);
     69 		assert_uint_eq(lzma_vli_size(vli * 3 + 39), i);
     70 	}
     71 }
     72 
     73 
     74 #ifdef HAVE_ENCODERS
     75 // Helper function for test_lzma_vli_encode
     76 // Encodes an input VLI and compares against a pre-computed value
     77 static void
     78 encode_single_call_mode(lzma_vli input, const uint8_t *expected,
     79 		uint32_t expected_len)
     80 {
     81 	uint8_t out[LZMA_VLI_BYTES_MAX];
     82 	size_t out_pos = 0;
     83 	assert_lzma_ret(lzma_vli_encode(input, NULL, out, &out_pos,
     84 			expected_len), LZMA_OK);
     85 	assert_uint_eq(out_pos, expected_len);
     86 	assert_array_eq(out, expected, expected_len);
     87 }
     88 
     89 
     90 // Helper function for test_lzma_vli_encode
     91 // Encodes an input VLI one byte at a time with the multi call
     92 // method. Then compares against a pre-computed value
     93 static void
     94 encode_multi_call_mode(lzma_vli input, const uint8_t *expected,
     95 		uint32_t expected_len)
     96 {
     97 	uint8_t out[LZMA_VLI_BYTES_MAX];
     98 	size_t out_pos = 0;
     99 	size_t vli_pos = 0;
    100 
    101 	for (uint32_t i = 1; i < expected_len; i++) {
    102 		assert_lzma_ret(lzma_vli_encode(input, &vli_pos, out,
    103 				&out_pos, i), LZMA_OK);
    104 		assert_uint_eq(out_pos, i);
    105 		assert_uint_eq(vli_pos, i);
    106 	}
    107 	assert_lzma_ret(lzma_vli_encode(input, &vli_pos, out, &out_pos,
    108 			expected_len), LZMA_STREAM_END);
    109 	assert_uint_eq(out_pos, expected_len);
    110 	assert_uint_eq(vli_pos, expected_len);
    111 	assert_array_eq(out, expected, expected_len);
    112 }
    113 #endif
    114 
    115 
    116 static void
    117 test_lzma_vli_encode(void)
    118 {
    119 #ifndef HAVE_ENCODERS
    120 	assert_skip("Encoder support disabled");
    121 #else
    122 	size_t vli_pos = 0;
    123 	uint8_t out[LZMA_VLI_BYTES_MAX];
    124 	uint8_t zeros[LZMA_VLI_BYTES_MAX];
    125 	memzero(out, LZMA_VLI_BYTES_MAX);
    126 	memzero(zeros, LZMA_VLI_BYTES_MAX);
    127 	size_t out_pos = 0;
    128 
    129 	// First test invalid input parameters
    130 	// VLI invalid
    131 	assert_lzma_ret(lzma_vli_encode(LZMA_VLI_UNKNOWN, &vli_pos, out,
    132 			&out_pos, sizeof(out)), LZMA_PROG_ERROR);
    133 	// Failure should not change params
    134 	assert_uint_eq(vli_pos, 0);
    135 	assert_uint_eq(out_pos, 0);
    136 	assert_array_eq(out, zeros, LZMA_VLI_BYTES_MAX);
    137 
    138 	assert_lzma_ret(lzma_vli_encode(LZMA_VLI_MAX + 1, &vli_pos, out,
    139 		&out_pos, sizeof(out)), LZMA_PROG_ERROR);
    140 	assert_uint_eq(vli_pos, 0);
    141 	assert_uint_eq(out_pos, 0);
    142 	assert_array_eq(out, zeros, LZMA_VLI_BYTES_MAX);
    143 
    144 	// 0 output size
    145 	assert_lzma_ret(lzma_vli_encode(one_byte_value, &vli_pos, out,
    146 			&out_pos, 0), LZMA_BUF_ERROR);
    147 	assert_uint_eq(vli_pos, 0);
    148 	assert_uint_eq(out_pos, 0);
    149 	assert_array_eq(out, zeros, LZMA_VLI_BYTES_MAX);
    150 
    151 	// Size of VLI does not fit in buffer
    152 	size_t phony_out_pos = 3;
    153 	assert_lzma_ret(lzma_vli_encode(one_byte_value, NULL, out,
    154 			&phony_out_pos, 2), LZMA_PROG_ERROR);
    155 
    156 	assert_lzma_ret(lzma_vli_encode(LZMA_VLI_MAX / 2, NULL, out,
    157 			&out_pos, 2), LZMA_PROG_ERROR);
    158 
    159 	// Test single-call mode (using vli_pos as NULL)
    160 	encode_single_call_mode(one_byte_value, one_byte,
    161 			sizeof(one_byte));
    162 	encode_single_call_mode(two_byte_value, two_bytes,
    163 			sizeof(two_bytes));
    164 	encode_single_call_mode(three_byte_value, three_bytes,
    165 			sizeof(three_bytes));
    166 	encode_single_call_mode(four_byte_value, four_bytes,
    167 			sizeof(four_bytes));
    168 	encode_single_call_mode(five_byte_value, five_bytes,
    169 			sizeof(five_bytes));
    170 	encode_single_call_mode(six_byte_value, six_bytes,
    171 			sizeof(six_bytes));
    172 	encode_single_call_mode(seven_byte_value, seven_bytes,
    173 			sizeof(seven_bytes));
    174 	encode_single_call_mode(eight_byte_value, eight_bytes,
    175 			sizeof(eight_bytes));
    176 	encode_single_call_mode(nine_byte_value, nine_bytes,
    177 			sizeof(nine_bytes));
    178 
    179 	// Test multi-call mode
    180 	encode_multi_call_mode(one_byte_value, one_byte,
    181 			sizeof(one_byte));
    182 	encode_multi_call_mode(two_byte_value, two_bytes,
    183 			sizeof(two_bytes));
    184 	encode_multi_call_mode(three_byte_value, three_bytes,
    185 			sizeof(three_bytes));
    186 	encode_multi_call_mode(four_byte_value, four_bytes,
    187 			sizeof(four_bytes));
    188 	encode_multi_call_mode(five_byte_value, five_bytes,
    189 			sizeof(five_bytes));
    190 	encode_multi_call_mode(six_byte_value, six_bytes,
    191 			sizeof(six_bytes));
    192 	encode_multi_call_mode(seven_byte_value, seven_bytes,
    193 			sizeof(seven_bytes));
    194 	encode_multi_call_mode(eight_byte_value, eight_bytes,
    195 			sizeof(eight_bytes));
    196 	encode_multi_call_mode(nine_byte_value, nine_bytes,
    197 			sizeof(nine_bytes));
    198 #endif
    199 }
    200 
    201 
    202 #ifdef HAVE_DECODERS
    203 static void
    204 decode_single_call_mode(const uint8_t *input, uint32_t input_len,
    205 		lzma_vli expected)
    206 {
    207 	lzma_vli out = 0;
    208 	size_t in_pos = 0;
    209 
    210 	assert_lzma_ret(lzma_vli_decode(&out, NULL, input, &in_pos,
    211 			input_len), LZMA_OK);
    212 	assert_uint_eq(in_pos, input_len);
    213 	assert_uint_eq(out, expected);
    214 }
    215 
    216 
    217 static void
    218 decode_multi_call_mode(const uint8_t *input, uint32_t input_len,
    219 		lzma_vli expected)
    220 {
    221 	lzma_vli out = 0;
    222 	size_t in_pos = 0;
    223 	size_t vli_pos = 0;
    224 
    225 	for (uint32_t i = 1; i < input_len; i++) {
    226 		assert_lzma_ret(lzma_vli_decode(&out, &vli_pos, input,
    227 				&in_pos, i), LZMA_OK);
    228 		assert_uint_eq(in_pos, i);
    229 		assert_uint_eq(vli_pos, i);
    230 	}
    231 
    232 	assert_lzma_ret(lzma_vli_decode(&out, &vli_pos, input, &in_pos,
    233 			input_len), LZMA_STREAM_END);
    234 	assert_uint_eq(in_pos, input_len);
    235 	assert_uint_eq(vli_pos, input_len);
    236 	assert_uint_eq(out, expected);
    237 }
    238 #endif
    239 
    240 
    241 static void
    242 test_lzma_vli_decode(void)
    243 {
    244 #ifndef HAVE_DECODERS
    245 	assert_skip("Decoder support disabled");
    246 #else
    247 	lzma_vli out = 0;
    248 	size_t in_pos = 0;
    249 
    250 	// First test invalid input params
    251 	// 0 in_size
    252 	assert_lzma_ret(lzma_vli_decode(&out, NULL, one_byte, &in_pos, 0),
    253 			LZMA_DATA_ERROR);
    254 	assert_uint_eq(out, 0);
    255 	assert_uint_eq(in_pos, 0);
    256 
    257 	// VLI encoded is invalid (last digit has leading 1 set)
    258 	uint8_t invalid_vli[3] = {0x80, 0x80, 0x80};
    259 	assert_lzma_ret(lzma_vli_decode(&out, NULL, invalid_vli, &in_pos,
    260 			sizeof(invalid_vli)), LZMA_DATA_ERROR);
    261 
    262 	// Bad vli_pos
    263 	size_t vli_pos = LZMA_VLI_BYTES_MAX;
    264 	assert_lzma_ret(lzma_vli_decode(&out, &vli_pos, invalid_vli, &in_pos,
    265 			sizeof(invalid_vli)), LZMA_PROG_ERROR);
    266 
    267 	// Bad in_pos
    268 	in_pos = sizeof(invalid_vli);
    269 	assert_lzma_ret(lzma_vli_decode(&out, &in_pos, invalid_vli, &in_pos,
    270 			sizeof(invalid_vli)), LZMA_BUF_ERROR);
    271 
    272 	// Test single call mode
    273 	decode_single_call_mode(one_byte, sizeof(one_byte),
    274 			one_byte_value);
    275 	decode_single_call_mode(two_bytes, sizeof(two_bytes),
    276 			two_byte_value);
    277 	decode_single_call_mode(three_bytes, sizeof(three_bytes),
    278 			three_byte_value);
    279 	decode_single_call_mode(four_bytes, sizeof(four_bytes),
    280 			four_byte_value);
    281 	decode_single_call_mode(five_bytes, sizeof(five_bytes),
    282 			five_byte_value);
    283 	decode_single_call_mode(six_bytes, sizeof(six_bytes),
    284 			six_byte_value);
    285 	decode_single_call_mode(seven_bytes, sizeof(seven_bytes),
    286 			seven_byte_value);
    287 	decode_single_call_mode(eight_bytes, sizeof(eight_bytes),
    288 			eight_byte_value);
    289 	decode_single_call_mode(nine_bytes, sizeof(nine_bytes),
    290 			nine_byte_value);
    291 
    292 	// Test multi call mode
    293 	decode_multi_call_mode(one_byte, sizeof(one_byte),
    294 			one_byte_value);
    295 	decode_multi_call_mode(two_bytes, sizeof(two_bytes),
    296 			two_byte_value);
    297 	decode_multi_call_mode(three_bytes, sizeof(three_bytes),
    298 			three_byte_value);
    299 	decode_multi_call_mode(four_bytes, sizeof(four_bytes),
    300 			four_byte_value);
    301 	decode_multi_call_mode(five_bytes, sizeof(five_bytes),
    302 			five_byte_value);
    303 	decode_multi_call_mode(six_bytes, sizeof(six_bytes),
    304 			six_byte_value);
    305 	decode_multi_call_mode(seven_bytes, sizeof(seven_bytes),
    306 			seven_byte_value);
    307 	decode_multi_call_mode(eight_bytes, sizeof(eight_bytes),
    308 			eight_byte_value);
    309 	decode_multi_call_mode(nine_bytes, sizeof(nine_bytes),
    310 			nine_byte_value);
    311 #endif
    312 }
    313 
    314 
    315 extern int
    316 main(int argc, char **argv)
    317 {
    318 	tuktest_start(argc, argv);
    319 	tuktest_run(test_lzma_vli_size);
    320 	tuktest_run(test_lzma_vli_encode);
    321 	tuktest_run(test_lzma_vli_decode);
    322 	return tuktest_end();
    323 }
    324