1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file vli_decoder.c 4207753Smm/// \brief Decodes variable-length integers 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm#include "common.h" 14207753Smm 15207753Smm 16207753Smmextern LZMA_API(lzma_ret) 17207753Smmlzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos, 18207753Smm const uint8_t *restrict in, size_t *restrict in_pos, 19207753Smm size_t in_size) 20207753Smm{ 21207753Smm // If we haven't been given vli_pos, work in single-call mode. 22207753Smm size_t vli_pos_internal = 0; 23207753Smm if (vli_pos == NULL) { 24207753Smm vli_pos = &vli_pos_internal; 25207753Smm *vli = 0; 26207753Smm 27207753Smm // If there's no input, use LZMA_DATA_ERROR. This way it is 28207753Smm // easy to decode VLIs from buffers that have known size, 29207753Smm // and get the correct error code in case the buffer is 30207753Smm // too short. 31207753Smm if (*in_pos >= in_size) 32207753Smm return LZMA_DATA_ERROR; 33207753Smm 34207753Smm } else { 35207753Smm // Initialize *vli when starting to decode a new integer. 36207753Smm if (*vli_pos == 0) 37207753Smm *vli = 0; 38207753Smm 39207753Smm // Validate the arguments. 40207753Smm if (*vli_pos >= LZMA_VLI_BYTES_MAX 41207753Smm || (*vli >> (*vli_pos * 7)) != 0) 42207753Smm return LZMA_PROG_ERROR;; 43207753Smm 44207753Smm if (*in_pos >= in_size) 45207753Smm return LZMA_BUF_ERROR; 46207753Smm } 47207753Smm 48207753Smm do { 49207753Smm // Read the next byte. Use a temporary variable so that we 50207753Smm // can update *in_pos immediately. 51207753Smm const uint8_t byte = in[*in_pos]; 52207753Smm ++*in_pos; 53207753Smm 54207753Smm // Add the newly read byte to *vli. 55207753Smm *vli += (lzma_vli)(byte & 0x7F) << (*vli_pos * 7); 56207753Smm ++*vli_pos; 57207753Smm 58207753Smm // Check if this is the last byte of a multibyte integer. 59207753Smm if ((byte & 0x80) == 0) { 60207753Smm // We don't allow using variable-length integers as 61207753Smm // padding i.e. the encoding must use the most the 62207753Smm // compact form. 63207753Smm if (byte == 0x00 && *vli_pos > 1) 64207753Smm return LZMA_DATA_ERROR; 65207753Smm 66207753Smm return vli_pos == &vli_pos_internal 67207753Smm ? LZMA_OK : LZMA_STREAM_END; 68207753Smm } 69207753Smm 70207753Smm // There is at least one more byte coming. If we have already 71207753Smm // read maximum number of bytes, the integer is considered 72207753Smm // corrupt. 73207753Smm // 74207753Smm // If we need bigger integers in future, old versions liblzma 75207753Smm // will confusingly indicate the file being corrupt istead of 76207753Smm // unsupported. I suppose it's still better this way, because 77207753Smm // in the foreseeable future (writing this in 2008) the only 78207753Smm // reason why files would appear having over 63-bit integers 79207753Smm // is that the files are simply corrupt. 80207753Smm if (*vli_pos == LZMA_VLI_BYTES_MAX) 81207753Smm return LZMA_DATA_ERROR; 82207753Smm 83207753Smm } while (*in_pos < in_size); 84207753Smm 85207753Smm return vli_pos == &vli_pos_internal ? LZMA_DATA_ERROR : LZMA_OK; 86207753Smm} 87