Coverage Report

Created: 2025-07-11 06:31

/src/fwupd/libfwupdplugin/fu-byte-array.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2017 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
0
#define G_LOG_DOMAIN "FuCommon"
8
9
#include "config.h"
10
11
#include "fu-byte-array.h"
12
#include "fu-common.h"
13
#include "fu-firmware-common.h"
14
#include "fu-mem.h"
15
16
/**
17
 * fu_byte_array_to_string:
18
 * @array: a #GByteArray
19
 *
20
 * Converts the byte array to a lowercase hex string.
21
 *
22
 * Returns: (transfer full): a string, which may be zero length
23
 *
24
 * Since: 1.8.9
25
 **/
26
gchar *
27
fu_byte_array_to_string(GByteArray *array)
28
0
{
29
0
  g_autoptr(GString) str = g_string_new(NULL);
30
0
  g_return_val_if_fail(array != NULL, NULL);
31
0
  for (guint i = 0; i < array->len; i++)
32
0
    g_string_append_printf(str, "%02x", array->data[i]);
33
0
  return g_string_free(g_steal_pointer(&str), FALSE);
34
0
}
35
36
/**
37
 * fu_byte_array_from_string:
38
 * @str: a hex string
39
 * @error: (nullable): optional return location for an error
40
 *
41
 * Converts a lowercase hex string to a byte array.
42
 *
43
 * Returns: (transfer full): a #GByteArray, or %NULL on error
44
 *
45
 * Since: 1.9.6
46
 **/
47
GByteArray *
48
fu_byte_array_from_string(const gchar *str, GError **error)
49
0
{
50
0
  gsize strsz;
51
0
  g_autoptr(GByteArray) buf = g_byte_array_new();
52
53
0
  g_return_val_if_fail(str != NULL, NULL);
54
0
  g_return_val_if_fail(error == NULL || *error == NULL, NULL);
55
56
0
  strsz = strlen(str);
57
0
  for (guint i = 0; i < strsz; i += 2) {
58
0
    guint8 value = 0;
59
0
    if (!fu_firmware_strparse_uint8_safe(str, strsz, i, &value, error))
60
0
      return NULL;
61
0
    fu_byte_array_append_uint8(buf, value);
62
0
  }
63
0
  return g_steal_pointer(&buf);
64
0
}
65
66
/**
67
 * fu_byte_array_append_uint8:
68
 * @array: a #GByteArray
69
 * @data: value
70
 *
71
 * Adds a 8 bit integer to a byte array.
72
 *
73
 * Since: 1.3.1
74
 **/
75
void
76
fu_byte_array_append_uint8(GByteArray *array, guint8 data)
77
178M
{
78
178M
  g_byte_array_append(array, &data, sizeof(data));
79
178M
}
80
81
/**
82
 * fu_byte_array_append_uint16:
83
 * @array: a #GByteArray
84
 * @data: value
85
 * @endian: endian type, e.g. #G_LITTLE_ENDIAN
86
 *
87
 * Adds a 16 bit integer to a byte array.
88
 *
89
 * Since: 1.3.1
90
 **/
91
void
92
fu_byte_array_append_uint16(GByteArray *array, guint16 data, FuEndianType endian)
93
719k
{
94
719k
  guint8 buf[2];
95
719k
  fu_memwrite_uint16(buf, data, endian);
96
719k
  g_byte_array_append(array, buf, sizeof(buf));
97
719k
}
98
99
/**
100
 * fu_byte_array_append_uint24:
101
 * @array: a #GByteArray
102
 * @data: value
103
 * @endian: endian type, e.g. #G_LITTLE_ENDIAN
104
 *
105
 * Adds a 24 bit integer to a byte array.
106
 *
107
 * Since: 1.8.13
108
 **/
109
void
110
fu_byte_array_append_uint24(GByteArray *array, guint32 data, FuEndianType endian)
111
0
{
112
0
  guint8 buf[3];
113
0
  fu_memwrite_uint24(buf, data, endian);
114
0
  g_byte_array_append(array, buf, sizeof(buf));
115
0
}
116
117
/**
118
 * fu_byte_array_append_uint32:
119
 * @array: a #GByteArray
120
 * @data: value
121
 * @endian: endian type, e.g. #G_LITTLE_ENDIAN
122
 *
123
 * Adds a 32 bit integer to a byte array.
124
 *
125
 * Since: 1.3.1
126
 **/
127
void
128
fu_byte_array_append_uint32(GByteArray *array, guint32 data, FuEndianType endian)
129
196k
{
130
196k
  guint8 buf[4];
131
196k
  fu_memwrite_uint32(buf, data, endian);
132
196k
  g_byte_array_append(array, buf, sizeof(buf));
133
196k
}
134
135
/**
136
 * fu_byte_array_append_uint64:
137
 * @array: a #GByteArray
138
 * @data: value
139
 * @endian: endian type, e.g. #G_LITTLE_ENDIAN
140
 *
141
 * Adds a 64 bit integer to a byte array.
142
 *
143
 * Since: 1.5.8
144
 **/
145
void
146
fu_byte_array_append_uint64(GByteArray *array, guint64 data, FuEndianType endian)
147
0
{
148
0
  guint8 buf[8];
149
0
  fu_memwrite_uint64(buf, data, endian);
150
0
  g_byte_array_append(array, buf, sizeof(buf));
151
0
}
152
153
/**
154
 * fu_byte_array_append_bytes:
155
 * @array: a #GByteArray
156
 * @bytes: data blob
157
 *
158
 * Adds the contents of a GBytes to a byte array.
159
 *
160
 * Since: 1.5.8
161
 **/
162
void
163
fu_byte_array_append_bytes(GByteArray *array, GBytes *bytes)
164
262k
{
165
262k
  g_byte_array_append(array, g_bytes_get_data(bytes, NULL), g_bytes_get_size(bytes));
166
262k
}
167
168
/**
169
 * fu_byte_array_set_size:
170
 * @array: a #GByteArray
171
 * @length:  the new size of the GByteArray
172
 * @data: the byte used to pad the array
173
 *
174
 * Sets the size of the GByteArray, expanding with @data as required.
175
 *
176
 * Since: 1.8.2
177
 **/
178
void
179
fu_byte_array_set_size(GByteArray *array, gsize length, guint8 data)
180
170k
{
181
170k
  guint oldlength = array->len;
182
170k
  g_return_if_fail(array != NULL);
183
170k
  g_return_if_fail(length < G_MAXUINT);
184
170k
  g_byte_array_set_size(array, length);
185
170k
  if (length > oldlength)
186
145k
    memset(array->data + oldlength, data, length - oldlength);
187
170k
}
188
189
/**
190
 * fu_byte_array_align_up:
191
 * @array: a #GByteArray
192
 * @alignment: align to this power of 2
193
 * @data: the byte used to pad the array
194
 *
195
 * Align a byte array length to a power of 2 boundary, where @alignment is the
196
 * bit position to align to. If @alignment is zero then @array is unchanged.
197
 *
198
 * Since: 1.6.0
199
 **/
200
void
201
fu_byte_array_align_up(GByteArray *array, guint8 alignment, guint8 data)
202
45.2k
{
203
45.2k
  fu_byte_array_set_size(array, fu_common_align_up(array->len, alignment), data);
204
45.2k
}
205
206
/**
207
 * fu_byte_array_compare:
208
 * @buf1: a data blob
209
 * @buf2: another #GByteArray
210
 * @error: (nullable): optional return location for an error
211
 *
212
 * Compares two buffers for equality.
213
 *
214
 * Returns: %TRUE if @buf1 and @buf2 are identical
215
 *
216
 * Since: 1.8.0
217
 **/
218
gboolean
219
fu_byte_array_compare(GByteArray *buf1, GByteArray *buf2, GError **error)
220
0
{
221
0
  g_return_val_if_fail(buf1 != NULL, FALSE);
222
0
  g_return_val_if_fail(buf2 != NULL, FALSE);
223
0
  g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
224
0
  return fu_memcmp_safe(buf1->data,
225
0
            buf1->len,
226
0
            0x0,
227
0
            buf2->data,
228
0
            buf2->len,
229
0
            0x0,
230
0
            MAX(buf1->len, buf2->len),
231
0
            error);
232
0
}