Coverage Report

Created: 2026-02-26 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupdplugin/fu-lzma-common.c
Line
Count
Source
1
/*
2
 * Copyright 2021 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include <lzma.h>
10
11
#include "fu-lzma-common.h"
12
13
/**
14
 * fu_lzma_decompress_bytes:
15
 * @blob: data
16
 * @memlimit: decompression memory limit, in bytes
17
 * @error: (nullable): optional return location for an error
18
 *
19
 * Decompresses a LZMA stream.
20
 *
21
 * Returns: (transfer full): decompressed data
22
 *
23
 * Since: 2.0.7
24
 **/
25
GBytes *
26
fu_lzma_decompress_bytes(GBytes *blob, guint64 memlimit, GError **error)
27
380
{
28
380
  const gsize tmpbufsz = 0x20000;
29
380
  lzma_ret rc;
30
380
  lzma_stream strm = LZMA_STREAM_INIT;
31
380
  g_autofree guint8 *tmpbuf = g_malloc0(tmpbufsz);
32
380
  g_autoptr(GByteArray) buf = g_byte_array_new();
33
34
380
  strm.next_in = g_bytes_get_data(blob, NULL);
35
380
  strm.avail_in = g_bytes_get_size(blob);
36
37
380
  rc = lzma_auto_decoder(&strm, memlimit, LZMA_TELL_UNSUPPORTED_CHECK);
38
380
  if (rc != LZMA_OK) {
39
0
    lzma_end(&strm);
40
0
    g_set_error(error,
41
0
          FWUPD_ERROR,
42
0
          FWUPD_ERROR_NOT_SUPPORTED,
43
0
          "failed to set up LZMA decoder rc=%u",
44
0
          rc);
45
0
    return NULL;
46
0
  }
47
3.07k
  do {
48
3.07k
    strm.next_out = tmpbuf;
49
3.07k
    strm.avail_out = tmpbufsz;
50
3.07k
    rc = lzma_code(&strm, LZMA_RUN);
51
3.07k
    if (rc != LZMA_OK && rc != LZMA_STREAM_END)
52
318
      break;
53
2.75k
    g_byte_array_append(buf, tmpbuf, tmpbufsz - strm.avail_out);
54
2.75k
  } while (rc == LZMA_OK);
55
380
  lzma_end(&strm);
56
57
  /* success */
58
380
  if (rc != LZMA_OK && rc != LZMA_STREAM_END) {
59
318
    g_set_error(error,
60
318
          FWUPD_ERROR,
61
318
          FWUPD_ERROR_NOT_SUPPORTED,
62
318
          "failed to decode LZMA data rc=%u",
63
318
          rc);
64
318
    return NULL;
65
318
  }
66
62
  return g_bytes_new(buf->data, buf->len);
67
380
}
68
69
/**
70
 * fu_lzma_compress_bytes:
71
 * @blob: data
72
 * @error: (nullable): optional return location for an error
73
 *
74
 * Compresses into a LZMA stream.
75
 *
76
 * Returns: (transfer full): compressed data
77
 *
78
 * Since: 1.9.8
79
 **/
80
GBytes *
81
fu_lzma_compress_bytes(GBytes *blob, GError **error)
82
1
{
83
1
  const gsize tmpbufsz = 0x20000;
84
1
  lzma_ret rc;
85
1
  lzma_stream strm = LZMA_STREAM_INIT;
86
1
  g_autofree guint8 *tmpbuf = g_malloc0(tmpbufsz);
87
1
  g_autoptr(GByteArray) buf = g_byte_array_new();
88
89
1
  strm.next_in = g_bytes_get_data(blob, NULL);
90
1
  strm.avail_in = g_bytes_get_size(blob);
91
92
  /* xz default compression level is 6, higher values increase CPU and memory usage */
93
1
  rc = lzma_easy_encoder(&strm, 6, LZMA_CHECK_CRC64);
94
1
  if (rc != LZMA_OK) {
95
0
    lzma_end(&strm);
96
0
    g_set_error(error,
97
0
          FWUPD_ERROR,
98
0
          FWUPD_ERROR_NOT_SUPPORTED,
99
0
          "failed to set up LZMA encoder rc=%u",
100
0
          rc);
101
0
    return NULL;
102
0
  }
103
1
  do {
104
1
    strm.next_out = tmpbuf;
105
1
    strm.avail_out = tmpbufsz;
106
1
    rc = lzma_code(&strm, LZMA_FINISH);
107
1
    if (rc != LZMA_OK && rc != LZMA_STREAM_END)
108
0
      break;
109
1
    g_byte_array_append(buf, tmpbuf, tmpbufsz - strm.avail_out);
110
1
  } while (rc == LZMA_OK);
111
1
  lzma_end(&strm);
112
113
  /* success */
114
1
  if (rc != LZMA_OK && rc != LZMA_STREAM_END) {
115
0
    g_set_error(error,
116
0
          FWUPD_ERROR,
117
0
          FWUPD_ERROR_NOT_SUPPORTED,
118
0
          "failed to encode LZMA data rc=%u",
119
0
          rc);
120
0
    return NULL;
121
0
  }
122
1
  return g_bytes_new(buf->data, buf->len);
123
1
}