Coverage Report

Created: 2025-11-24 06:59

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
1.50k
{
28
1.50k
  const gsize tmpbufsz = 0x20000;
29
1.50k
  lzma_ret rc;
30
1.50k
  lzma_stream strm = LZMA_STREAM_INIT;
31
1.50k
  g_autofree guint8 *tmpbuf = g_malloc0(tmpbufsz);
32
1.50k
  g_autoptr(GByteArray) buf = g_byte_array_new();
33
34
1.50k
  strm.next_in = g_bytes_get_data(blob, NULL);
35
1.50k
  strm.avail_in = g_bytes_get_size(blob);
36
37
1.50k
  rc = lzma_auto_decoder(&strm, memlimit, LZMA_TELL_UNSUPPORTED_CHECK);
38
1.50k
  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
4.36k
  do {
48
4.36k
    strm.next_out = tmpbuf;
49
4.36k
    strm.avail_out = tmpbufsz;
50
4.36k
    rc = lzma_code(&strm, LZMA_RUN);
51
4.36k
    if (rc != LZMA_OK && rc != LZMA_STREAM_END)
52
623
      break;
53
3.74k
    g_byte_array_append(buf, tmpbuf, tmpbufsz - strm.avail_out);
54
3.74k
  } while (rc == LZMA_OK);
55
1.50k
  lzma_end(&strm);
56
57
  /* success */
58
1.50k
  if (rc != LZMA_OK && rc != LZMA_STREAM_END) {
59
623
    g_set_error(error,
60
623
          FWUPD_ERROR,
61
623
          FWUPD_ERROR_NOT_SUPPORTED,
62
623
          "failed to decode LZMA data rc=%u",
63
623
          rc);
64
623
    return NULL;
65
623
  }
66
883
  return g_bytes_new(buf->data, buf->len);
67
1.50k
}
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
146
{
83
146
  const gsize tmpbufsz = 0x20000;
84
146
  lzma_ret rc;
85
146
  lzma_stream strm = LZMA_STREAM_INIT;
86
146
  g_autofree guint8 *tmpbuf = g_malloc0(tmpbufsz);
87
146
  g_autoptr(GByteArray) buf = g_byte_array_new();
88
89
146
  strm.next_in = g_bytes_get_data(blob, NULL);
90
146
  strm.avail_in = g_bytes_get_size(blob);
91
92
  /* xz default compression level is 6, higher values increase CPU and memory usage */
93
146
  rc = lzma_easy_encoder(&strm, 6, LZMA_CHECK_CRC64);
94
146
  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
146
  do {
104
146
    strm.next_out = tmpbuf;
105
146
    strm.avail_out = tmpbufsz;
106
146
    rc = lzma_code(&strm, LZMA_FINISH);
107
146
    if (rc != LZMA_OK && rc != LZMA_STREAM_END)
108
0
      break;
109
146
    g_byte_array_append(buf, tmpbuf, tmpbufsz - strm.avail_out);
110
146
  } while (rc == LZMA_OK);
111
146
  lzma_end(&strm);
112
113
  /* success */
114
146
  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
146
  return g_bytes_new(buf->data, buf->len);
123
146
}