Rizin
unix-like reverse engineering framework and cli tools
vli_decoder.c
Go to the documentation of this file.
1 //
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
12 
13 #include "common.h"
14 
15 
17 lzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos,
18  const uint8_t *restrict in, size_t *restrict in_pos,
19  size_t in_size)
20 {
21  // If we haven't been given vli_pos, work in single-call mode.
22  size_t vli_pos_internal = 0;
23  if (vli_pos == NULL) {
24  vli_pos = &vli_pos_internal;
25  *vli = 0;
26 
27  // If there's no input, use LZMA_DATA_ERROR. This way it is
28  // easy to decode VLIs from buffers that have known size,
29  // and get the correct error code in case the buffer is
30  // too short.
31  if (*in_pos >= in_size)
32  return LZMA_DATA_ERROR;
33 
34  } else {
35  // Initialize *vli when starting to decode a new integer.
36  if (*vli_pos == 0)
37  *vli = 0;
38 
39  // Validate the arguments.
41  || (*vli >> (*vli_pos * 7)) != 0)
42  return LZMA_PROG_ERROR;;
43 
44  if (*in_pos >= in_size)
45  return LZMA_BUF_ERROR;
46  }
47 
48  do {
49  // Read the next byte. Use a temporary variable so that we
50  // can update *in_pos immediately.
51  const uint8_t byte = in[*in_pos];
52  ++*in_pos;
53 
54  // Add the newly read byte to *vli.
55  *vli += (lzma_vli)(byte & 0x7F) << (*vli_pos * 7);
56  ++*vli_pos;
57 
58  // Check if this is the last byte of a multibyte integer.
59  if ((byte & 0x80) == 0) {
60  // We don't allow using variable-length integers as
61  // padding i.e. the encoding must use the most the
62  // compact form.
63  if (byte == 0x00 && *vli_pos > 1)
64  return LZMA_DATA_ERROR;
65 
66  return vli_pos == &vli_pos_internal
68  }
69 
70  // There is at least one more byte coming. If we have already
71  // read maximum number of bytes, the integer is considered
72  // corrupt.
73  //
74  // If we need bigger integers in future, old versions liblzma
75  // will confusingly indicate the file being corrupt instead of
76  // unsupported. I suppose it's still better this way, because
77  // in the foreseeable future (writing this in 2008) the only
78  // reason why files would appear having over 63-bit integers
79  // is that the files are simply corrupt.
81  return LZMA_DATA_ERROR;
82 
83  } while (*in_pos < in_size);
84 
85  return vli_pos == &vli_pos_internal ? LZMA_DATA_ERROR : LZMA_OK;
86 }
const lzma_allocator const uint8_t size_t * in_pos
Definition: block.h:579
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
const lzma_allocator const uint8_t * in
Definition: block.h:527
#define NULL
Definition: cris-opc.c:27
#define restrict
unsigned char uint8_t
Definition: sftypes.h:31
Definitions common to the whole liblzma library.
#define LZMA_VLI_BYTES_MAX
Maximum supported encoded length of variable length integers.
Definition: vli.h:44
uint64_t lzma_vli
Variable-length integer type.
Definition: vli.h:63
size_t * vli_pos
Definition: vli.h:115
LZMA_API(lzma_ret)
Definition: vli_decoder.c:16
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_DATA_ERROR
Data is corrupt.
Definition: base.h:172
@ LZMA_STREAM_END
End of stream was reached.
Definition: base.h:63
@ LZMA_BUF_ERROR
No progress is possible.
Definition: base.h:191
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58