Coverage Report

Created: 2025-06-16 07:00

/src/xz/src/liblzma/common/vli_decoder.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: 0BSD
2
3
///////////////////////////////////////////////////////////////////////////////
4
//
5
/// \file       vli_decoder.c
6
/// \brief      Decodes variable-length integers
7
//
8
//  Author:     Lasse Collin
9
//
10
///////////////////////////////////////////////////////////////////////////////
11
12
#include "common.h"
13
14
15
extern LZMA_API(lzma_ret)
16
lzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos,
17
    const uint8_t *restrict in, size_t *restrict in_pos,
18
    size_t in_size)
19
123k
{
20
  // If we haven't been given vli_pos, work in single-call mode.
21
123k
  size_t vli_pos_internal = 0;
22
123k
  if (vli_pos == NULL) {
23
119k
    vli_pos = &vli_pos_internal;
24
119k
    *vli = 0;
25
26
    // If there's no input, use LZMA_DATA_ERROR. This way it is
27
    // easy to decode VLIs from buffers that have known size,
28
    // and get the correct error code in case the buffer is
29
    // too short.
30
119k
    if (*in_pos >= in_size)
31
170
      return LZMA_DATA_ERROR;
32
33
119k
  } else {
34
    // Initialize *vli when starting to decode a new integer.
35
4.08k
    if (*vli_pos == 0)
36
4.06k
      *vli = 0;
37
38
    // Validate the arguments.
39
4.08k
    if (*vli_pos >= LZMA_VLI_BYTES_MAX
40
4.08k
        || (*vli >> (*vli_pos * 7)) != 0)
41
4.08k
      return LZMA_PROG_ERROR;;
42
43
4.08k
    if (*in_pos >= in_size)
44
0
      return LZMA_BUF_ERROR;
45
4.08k
  }
46
47
197k
  do {
48
    // Read the next byte. Use a temporary variable so that we
49
    // can update *in_pos immediately.
50
197k
    const uint8_t byte = in[*in_pos];
51
197k
    ++*in_pos;
52
53
    // Add the newly read byte to *vli.
54
197k
    *vli += (lzma_vli)(byte & 0x7F) << (*vli_pos * 7);
55
197k
    ++*vli_pos;
56
57
    // Check if this is the last byte of a multibyte integer.
58
197k
    if ((byte & 0x80) == 0) {
59
      // We don't allow using variable-length integers as
60
      // padding i.e. the encoding must use the most the
61
      // compact form.
62
122k
      if (byte == 0x00 && *vli_pos > 1)
63
481
        return LZMA_DATA_ERROR;
64
65
122k
      return vli_pos == &vli_pos_internal
66
122k
          ? LZMA_OK : LZMA_STREAM_END;
67
122k
    }
68
69
    // There is at least one more byte coming. If we have already
70
    // read maximum number of bytes, the integer is considered
71
    // corrupt.
72
    //
73
    // If we need bigger integers in future, old versions liblzma
74
    // will confusingly indicate the file being corrupt instead of
75
    // unsupported. I suppose it's still better this way, because
76
    // in the foreseeable future (writing this in 2008) the only
77
    // reason why files would appear having over 63-bit integers
78
    // is that the files are simply corrupt.
79
74.9k
    if (*vli_pos == LZMA_VLI_BYTES_MAX)
80
109
      return LZMA_DATA_ERROR;
81
82
74.9k
  } while (*in_pos < in_size);
83
84
314
  return vli_pos == &vli_pos_internal ? LZMA_DATA_ERROR : LZMA_OK;
85
122k
}