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