Coverage Report

Created: 2025-12-14 06:56

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