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