Coverage Report

Created: 2026-06-15 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/fu-uf2-struct.c
Line
Count
Source
1
/*
2
 * This file is auto-generated, do not modify!
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include <glib.h>
10
11
#include "fu-uf2-struct.h"
12
#include "fu-byte-array.h"
13
#include "fu-bytes.h"
14
#include "fu-mem-private.h"
15
#include "fu-string.h"
16
17
#ifdef G_LOG_DOMAIN
18
  #undef G_LOG_DOMAIN
19
#endif
20
0
#define G_LOG_DOMAIN "FuStruct"
21
22
/**
23
 * fu_uf2_firmware_block_flags_to_string:
24
 * @val: value, e.g. %FU_UF2_FIRMWARE_BLOCK_FLAG_NOFLASH
25
 *
26
 * Converts an enumerated value to a string.
27
 *
28
 * Returns: identifier string
29
 **/
30
static const gchar *
31
fu_uf2_firmware_block_flags_to_string(FuUf2FirmwareBlockFlags val)
32
0
{
33
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_NONE)
34
0
        return "none";
35
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_NOFLASH)
36
0
        return "noflash";
37
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_IS_CONTAINER)
38
0
        return "is-container";
39
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_HAS_FAMILY)
40
0
        return "has-family";
41
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_HAS_MD5)
42
0
        return "has-md5";
43
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_HAS_EXTENSION_TAG)
44
0
        return "has-extension-tag";
45
0
    return NULL;
46
0
}
47
48
/**
49
 * fu_uf2_firmware_tag_to_string:
50
 * @val: value, e.g. %FU_UF2_FIRMWARE_TAG_DESCRIPTION
51
 *
52
 * Converts an enumerated value to a string.
53
 *
54
 * Returns: identifier string
55
 **/
56
const gchar *
57
fu_uf2_firmware_tag_to_string(FuUf2FirmwareTag val)
58
8
{
59
8
    if (val == FU_UF2_FIRMWARE_TAG_VERSION)
60
0
        return "version";
61
8
    if (val == FU_UF2_FIRMWARE_TAG_DESCRIPTION)
62
0
        return "description";
63
8
    if (val == FU_UF2_FIRMWARE_TAG_PAGE_SZ)
64
0
        return "page-sz";
65
8
    if (val == FU_UF2_FIRMWARE_TAG_SHA2)
66
0
        return "sha2";
67
8
    if (val == FU_UF2_FIRMWARE_TAG_DEVICE_ID)
68
0
        return "device-id";
69
8
    return NULL;
70
8
}
71
/**
72
 * fu_struct_uf2_extension_ref: (skip):
73
 **/
74
FuStructUf2Extension *
75
fu_struct_uf2_extension_ref(FuStructUf2Extension *st)
76
0
{
77
0
    g_return_val_if_fail(st != NULL, NULL);
78
0
    st->refcount++;
79
0
    return st;
80
0
}
81
/**
82
 * fu_struct_uf2_extension_unref: (skip):
83
 **/
84
void
85
fu_struct_uf2_extension_unref(FuStructUf2Extension *st)
86
14.8k
{
87
14.8k
    g_return_if_fail(st != NULL);
88
14.8k
    if (st->refcount == 0) {
89
0
        g_critical("FuStructUf2Extension refcount already zero");
90
0
        return;
91
0
    }
92
14.8k
    if (--st->refcount > 0)
93
0
        return;
94
14.8k
    if (st->buf != NULL)
95
14.8k
        g_byte_array_unref(st->buf);
96
14.8k
    g_free(st);
97
14.8k
}
98
/**
99
 * fu_struct_uf2_extension_new_internal: (skip):
100
 **/
101
static FuStructUf2Extension *
102
fu_struct_uf2_extension_new_internal(void)
103
14.8k
{
104
14.8k
    FuStructUf2Extension *st = g_new0(FuStructUf2Extension, 1);
105
14.8k
    st->refcount = 1;
106
14.8k
    return st;
107
14.8k
}
108
109
/* getters */
110
/**
111
 * fu_struct_uf2_extension_get_size: (skip):
112
 **/
113
guint8
114
fu_struct_uf2_extension_get_size(const FuStructUf2Extension *st)
115
13.5k
{
116
13.5k
    g_return_val_if_fail(st != NULL, 0x0);
117
13.5k
    return st->buf->data[0];
118
13.5k
}
119
/**
120
 * fu_struct_uf2_extension_get_tag: (skip):
121
 **/
122
FuUf2FirmwareTag
123
fu_struct_uf2_extension_get_tag(const FuStructUf2Extension *st)
124
13.3k
{
125
13.3k
    g_return_val_if_fail(st != NULL, 0x0);
126
13.3k
    return fu_memread_uint24(st->buf->data + 1, G_LITTLE_ENDIAN);
127
13.3k
}
128
129
/* setters */
130
/**
131
 * fu_struct_uf2_extension_set_size: (skip):
132
 **/
133
void
134
fu_struct_uf2_extension_set_size(FuStructUf2Extension *st, guint8 value)
135
867
{
136
867
    g_return_if_fail(st != NULL);
137
867
    st->buf->data[0] = value;
138
867
}
139
/**
140
 * fu_struct_uf2_extension_set_tag: (skip):
141
 **/
142
void
143
fu_struct_uf2_extension_set_tag(FuStructUf2Extension *st, FuUf2FirmwareTag value)
144
867
{
145
867
    g_return_if_fail(st != NULL);
146
867
    fu_memwrite_uint24(st->buf->data + 1, value, G_LITTLE_ENDIAN);
147
867
}
148
/**
149
 * fu_struct_uf2_extension_new: (skip):
150
 **/
151
FuStructUf2Extension *
152
fu_struct_uf2_extension_new(void)
153
1.31k
{
154
1.31k
    FuStructUf2Extension *st = fu_struct_uf2_extension_new_internal();
155
1.31k
    st->buf = g_byte_array_sized_new(4);
156
1.31k
    fu_byte_array_set_size(st->buf, 4, 0x0);
157
1.31k
    return st;
158
1.31k
}
159
/**
160
 * fu_struct_uf2_extension_to_string: (skip):
161
 **/
162
static gchar *
163
fu_struct_uf2_extension_to_string(const FuStructUf2Extension *st)
164
0
{
165
0
    g_autoptr(GString) str = g_string_new("FuStructUf2Extension:\n");
166
0
    g_return_val_if_fail(st != NULL, NULL);
167
0
    g_string_append_printf(str, "  size: 0x%x\n",
168
0
                           (guint) fu_struct_uf2_extension_get_size(st));
169
0
    {
170
0
        const gchar *tmp = fu_uf2_firmware_tag_to_string(fu_struct_uf2_extension_get_tag(st));
171
0
        if (tmp != NULL) {
172
0
            g_string_append_printf(str, "  tag: 0x%x [%s]\n", (guint) fu_struct_uf2_extension_get_tag(st), tmp);
173
0
        } else {
174
0
            g_string_append_printf(str, "  tag: 0x%x\n", (guint) fu_struct_uf2_extension_get_tag(st));
175
0
        }
176
0
    }
177
0
    if (str->len > 0)
178
0
        g_string_set_size(str, str->len - 1);
179
0
    return g_string_free(g_steal_pointer(&str), FALSE);
180
0
}
181
static gboolean
182
fu_struct_uf2_extension_parse_internal(FuStructUf2Extension *st, GError **error)
183
13.5k
{
184
13.5k
    if (g_log_get_debug_enabled()) {
185
0
        g_autofree gchar *str = fu_struct_uf2_extension_to_string(st);
186
0
        g_debug("%s", str);
187
0
    }
188
13.5k
    return TRUE;
189
13.5k
}
190
191
/**
192
 * fu_struct_uf2_extension_parse: (skip):
193
 **/
194
FuStructUf2Extension *
195
fu_struct_uf2_extension_parse(const guint8 *buf, gsize bufsz, gsize offset, GError **error)
196
13.5k
{
197
13.5k
    g_autoptr(FuStructUf2Extension) st = fu_struct_uf2_extension_new_internal();
198
13.5k
    g_return_val_if_fail(buf != NULL, NULL);
199
13.5k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
200
13.5k
    if (!fu_memchk_read(bufsz, offset, 4, error)) {
201
7
        g_prefix_error_literal(error, "invalid struct FuStructUf2Extension: ");
202
7
        return NULL;
203
7
    }
204
13.5k
    st->buf = g_byte_array_new();
205
13.5k
    g_byte_array_append(st->buf, buf + offset, 4);
206
13.5k
    if (!fu_struct_uf2_extension_parse_internal(st, error))
207
0
        return NULL;
208
13.5k
    return g_steal_pointer(&st);
209
13.5k
}
210
/**
211
 * fu_struct_uf2_ref: (skip):
212
 **/
213
FuStructUf2 *
214
fu_struct_uf2_ref(FuStructUf2 *st)
215
0
{
216
0
    g_return_val_if_fail(st != NULL, NULL);
217
0
    st->refcount++;
218
0
    return st;
219
0
}
220
/**
221
 * fu_struct_uf2_unref: (skip):
222
 **/
223
void
224
fu_struct_uf2_unref(FuStructUf2 *st)
225
2.25k
{
226
2.25k
    g_return_if_fail(st != NULL);
227
2.25k
    if (st->refcount == 0) {
228
0
        g_critical("FuStructUf2 refcount already zero");
229
0
        return;
230
0
    }
231
2.25k
    if (--st->refcount > 0)
232
0
        return;
233
2.25k
    if (st->buf != NULL)
234
1.31k
        g_byte_array_unref(st->buf);
235
2.25k
    g_free(st);
236
2.25k
}
237
/**
238
 * fu_struct_uf2_new_internal: (skip):
239
 **/
240
static FuStructUf2 *
241
fu_struct_uf2_new_internal(void)
242
2.25k
{
243
2.25k
    FuStructUf2 *st = g_new0(FuStructUf2, 1);
244
2.25k
    st->refcount = 1;
245
2.25k
    return st;
246
2.25k
}
247
248
/* getters */
249
/**
250
 * fu_struct_uf2_get_magic0: (skip):
251
 **/
252
static guint32
253
fu_struct_uf2_get_magic0(const FuStructUf2 *st)
254
1.35k
{
255
1.35k
    g_return_val_if_fail(st != NULL, 0x0);
256
1.35k
    return fu_memread_uint32(st->buf->data + 0, G_LITTLE_ENDIAN);
257
1.35k
}
258
/**
259
 * fu_struct_uf2_get_magic1: (skip):
260
 **/
261
static guint32
262
fu_struct_uf2_get_magic1(const FuStructUf2 *st)
263
1.26k
{
264
1.26k
    g_return_val_if_fail(st != NULL, 0x0);
265
1.26k
    return fu_memread_uint32(st->buf->data + 4, G_LITTLE_ENDIAN);
266
1.26k
}
267
/**
268
 * fu_struct_uf2_get_flags: (skip):
269
 **/
270
FuUf2FirmwareBlockFlags
271
fu_struct_uf2_get_flags(const FuStructUf2 *st)
272
1.12k
{
273
1.12k
    g_return_val_if_fail(st != NULL, 0x0);
274
1.12k
    return fu_memread_uint32(st->buf->data + 8, G_LITTLE_ENDIAN);
275
1.12k
}
276
/**
277
 * fu_struct_uf2_get_target_addr: (skip):
278
 **/
279
guint32
280
fu_struct_uf2_get_target_addr(const FuStructUf2 *st)
281
410
{
282
410
    g_return_val_if_fail(st != NULL, 0x0);
283
410
    return fu_memread_uint32(st->buf->data + 12, G_LITTLE_ENDIAN);
284
410
}
285
/**
286
 * fu_struct_uf2_get_payload_size: (skip):
287
 **/
288
guint32
289
fu_struct_uf2_get_payload_size(const FuStructUf2 *st)
290
1.11k
{
291
1.11k
    g_return_val_if_fail(st != NULL, 0x0);
292
1.11k
    return fu_memread_uint32(st->buf->data + 16, G_LITTLE_ENDIAN);
293
1.11k
}
294
/**
295
 * fu_struct_uf2_get_block_no: (skip):
296
 **/
297
guint32
298
fu_struct_uf2_get_block_no(const FuStructUf2 *st)
299
1.15k
{
300
1.15k
    g_return_val_if_fail(st != NULL, 0x0);
301
1.15k
    return fu_memread_uint32(st->buf->data + 20, G_LITTLE_ENDIAN);
302
1.15k
}
303
/**
304
 * fu_struct_uf2_get_num_blocks: (skip):
305
 **/
306
guint32
307
fu_struct_uf2_get_num_blocks(const FuStructUf2 *st)
308
1.05k
{
309
1.05k
    g_return_val_if_fail(st != NULL, 0x0);
310
1.05k
    return fu_memread_uint32(st->buf->data + 24, G_LITTLE_ENDIAN);
311
1.05k
}
312
/**
313
 * fu_struct_uf2_get_family_id: (skip):
314
 **/
315
guint32
316
fu_struct_uf2_get_family_id(const FuStructUf2 *st)
317
780
{
318
780
    g_return_val_if_fail(st != NULL, 0x0);
319
780
    return fu_memread_uint32(st->buf->data + 28, G_LITTLE_ENDIAN);
320
780
}
321
/**
322
 * fu_struct_uf2_get_data: (skip):
323
 **/
324
const guint8 *
325
fu_struct_uf2_get_data(const FuStructUf2 *st, gsize *bufsz)
326
1.04k
{
327
1.04k
    g_return_val_if_fail(st != NULL, NULL);
328
1.04k
    if (bufsz != NULL)
329
0
        *bufsz = 476;
330
1.04k
    return st->buf->data + 32;
331
1.04k
}
332
/**
333
 * fu_struct_uf2_get_magic_end: (skip):
334
 **/
335
static guint32
336
fu_struct_uf2_get_magic_end(const FuStructUf2 *st)
337
1.29k
{
338
1.29k
    g_return_val_if_fail(st != NULL, 0x0);
339
1.29k
    return fu_memread_uint32(st->buf->data + 508, G_LITTLE_ENDIAN);
340
1.29k
}
341
342
/* setters */
343
/**
344
 * fu_struct_uf2_set_magic0: (skip):
345
 **/
346
static void
347
fu_struct_uf2_set_magic0(FuStructUf2 *st, guint32 value)
348
918
{
349
918
    g_return_if_fail(st != NULL);
350
918
    fu_memwrite_uint32(st->buf->data + 0, value, G_LITTLE_ENDIAN);
351
918
}
352
/**
353
 * fu_struct_uf2_set_magic1: (skip):
354
 **/
355
static void
356
fu_struct_uf2_set_magic1(FuStructUf2 *st, guint32 value)
357
918
{
358
918
    g_return_if_fail(st != NULL);
359
918
    fu_memwrite_uint32(st->buf->data + 4, value, G_LITTLE_ENDIAN);
360
918
}
361
/**
362
 * fu_struct_uf2_set_flags: (skip):
363
 **/
364
void
365
fu_struct_uf2_set_flags(FuStructUf2 *st, FuUf2FirmwareBlockFlags value)
366
918
{
367
918
    g_return_if_fail(st != NULL);
368
918
    fu_memwrite_uint32(st->buf->data + 8, value, G_LITTLE_ENDIAN);
369
918
}
370
/**
371
 * fu_struct_uf2_set_target_addr: (skip):
372
 **/
373
void
374
fu_struct_uf2_set_target_addr(FuStructUf2 *st, guint32 value)
375
918
{
376
918
    g_return_if_fail(st != NULL);
377
918
    fu_memwrite_uint32(st->buf->data + 12, value, G_LITTLE_ENDIAN);
378
918
}
379
/**
380
 * fu_struct_uf2_set_payload_size: (skip):
381
 **/
382
void
383
fu_struct_uf2_set_payload_size(FuStructUf2 *st, guint32 value)
384
918
{
385
918
    g_return_if_fail(st != NULL);
386
918
    fu_memwrite_uint32(st->buf->data + 16, value, G_LITTLE_ENDIAN);
387
918
}
388
/**
389
 * fu_struct_uf2_set_block_no: (skip):
390
 **/
391
void
392
fu_struct_uf2_set_block_no(FuStructUf2 *st, guint32 value)
393
918
{
394
918
    g_return_if_fail(st != NULL);
395
918
    fu_memwrite_uint32(st->buf->data + 20, value, G_LITTLE_ENDIAN);
396
918
}
397
/**
398
 * fu_struct_uf2_set_num_blocks: (skip):
399
 **/
400
void
401
fu_struct_uf2_set_num_blocks(FuStructUf2 *st, guint32 value)
402
918
{
403
918
    g_return_if_fail(st != NULL);
404
918
    fu_memwrite_uint32(st->buf->data + 24, value, G_LITTLE_ENDIAN);
405
918
}
406
/**
407
 * fu_struct_uf2_set_family_id: (skip):
408
 **/
409
void
410
fu_struct_uf2_set_family_id(FuStructUf2 *st, guint32 value)
411
918
{
412
918
    g_return_if_fail(st != NULL);
413
918
    fu_memwrite_uint32(st->buf->data + 28, value, G_LITTLE_ENDIAN);
414
918
}
415
/**
416
 * fu_struct_uf2_set_data: (skip):
417
 **/
418
gboolean
419
fu_struct_uf2_set_data(FuStructUf2 *st, const guint8 *buf, gsize bufsz, GError **error)
420
918
{
421
918
    g_return_val_if_fail(st != NULL, FALSE);
422
918
    g_return_val_if_fail(buf != NULL, FALSE);
423
918
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
424
918
    return fu_memcpy_safe(st->buf->data, st->buf->len, 32, buf, bufsz, 0x0, bufsz, error);
425
918
}
426
/**
427
 * fu_struct_uf2_set_magic_end: (skip):
428
 **/
429
static void
430
fu_struct_uf2_set_magic_end(FuStructUf2 *st, guint32 value)
431
918
{
432
918
    g_return_if_fail(st != NULL);
433
918
    fu_memwrite_uint32(st->buf->data + 508, value, G_LITTLE_ENDIAN);
434
918
}
435
/**
436
 * fu_struct_uf2_new: (skip):
437
 **/
438
FuStructUf2 *
439
fu_struct_uf2_new(void)
440
918
{
441
918
    FuStructUf2 *st = fu_struct_uf2_new_internal();
442
918
    st->buf = g_byte_array_sized_new(512);
443
918
    fu_byte_array_set_size(st->buf, 512, 0x0);
444
918
    fu_struct_uf2_set_magic0(st, 0x0A324655);
445
918
    fu_struct_uf2_set_magic1(st, 0x9E5D5157);
446
918
    fu_struct_uf2_set_magic_end(st, 0x0AB16F30);
447
918
    return st;
448
918
}
449
/**
450
 * fu_struct_uf2_to_string: (skip):
451
 **/
452
static gchar *
453
fu_struct_uf2_to_string(const FuStructUf2 *st)
454
0
{
455
0
    g_autoptr(GString) str = g_string_new("FuStructUf2:\n");
456
0
    g_return_val_if_fail(st != NULL, NULL);
457
0
    g_string_append_printf(str, "  magic0: 0x%x\n",
458
0
                           (guint) fu_struct_uf2_get_magic0(st));
459
0
    g_string_append_printf(str, "  magic1: 0x%x\n",
460
0
                           (guint) fu_struct_uf2_get_magic1(st));
461
0
    {
462
0
        const gchar *tmp = fu_uf2_firmware_block_flags_to_string(fu_struct_uf2_get_flags(st));
463
0
        if (tmp != NULL) {
464
0
            g_string_append_printf(str, "  flags: 0x%x [%s]\n", (guint) fu_struct_uf2_get_flags(st), tmp);
465
0
        } else {
466
0
            g_string_append_printf(str, "  flags: 0x%x\n", (guint) fu_struct_uf2_get_flags(st));
467
0
        }
468
0
    }
469
0
    g_string_append_printf(str, "  target_addr: 0x%x\n",
470
0
                           (guint) fu_struct_uf2_get_target_addr(st));
471
0
    g_string_append_printf(str, "  payload_size: 0x%x\n",
472
0
                           (guint) fu_struct_uf2_get_payload_size(st));
473
0
    g_string_append_printf(str, "  block_no: 0x%x\n",
474
0
                           (guint) fu_struct_uf2_get_block_no(st));
475
0
    g_string_append_printf(str, "  num_blocks: 0x%x\n",
476
0
                           (guint) fu_struct_uf2_get_num_blocks(st));
477
0
    g_string_append_printf(str, "  family_id: 0x%x\n",
478
0
                           (guint) fu_struct_uf2_get_family_id(st));
479
0
    {
480
0
        gsize bufsz = 0;
481
0
        const guint8 *buf = fu_struct_uf2_get_data(st, &bufsz);
482
0
        g_autoptr(GString) tmp = g_string_new(NULL);
483
0
        for (gsize i = 0; i < bufsz; i++)
484
0
            g_string_append_printf(tmp, "%02X", buf[i]);
485
0
        g_string_append_printf(str, "  data: 0x%s\n", tmp->str);
486
0
    }
487
0
    g_string_append_printf(str, "  magic_end: 0x%x\n",
488
0
                           (guint) fu_struct_uf2_get_magic_end(st));
489
0
    if (str->len > 0)
490
0
        g_string_set_size(str, str->len - 1);
491
0
    return g_string_free(g_steal_pointer(&str), FALSE);
492
0
}
493
static gboolean
494
fu_struct_uf2_validate_internal(FuStructUf2 *st, GError **error)
495
1.29k
{
496
1.29k
    g_return_val_if_fail(st != NULL, FALSE);
497
1.29k
    if (fu_struct_uf2_get_magic0(st) != 0x0A324655) {
498
62
        g_set_error(error,
499
62
                    FWUPD_ERROR,
500
62
                    FWUPD_ERROR_INVALID_DATA,
501
62
                    "constant FuStructUf2.magic0 was not valid, "
502
62
                    "expected 0x%x and got 0x%x",
503
62
                    (guint) 0x0A324655,
504
62
                    (guint) fu_struct_uf2_get_magic0(st));
505
62
        return FALSE;
506
62
    }
507
1.23k
    if (fu_struct_uf2_get_magic1(st) != 0x9E5D5157) {
508
26
        g_set_error(error,
509
26
                    FWUPD_ERROR,
510
26
                    FWUPD_ERROR_INVALID_DATA,
511
26
                    "constant FuStructUf2.magic1 was not valid, "
512
26
                    "expected 0x%x and got 0x%x",
513
26
                    (guint) 0x9E5D5157,
514
26
                    (guint) fu_struct_uf2_get_magic1(st));
515
26
        return FALSE;
516
26
    }
517
1.20k
    if (fu_struct_uf2_get_magic_end(st) != 0x0AB16F30) {
518
89
        g_set_error(error,
519
89
                    FWUPD_ERROR,
520
89
                    FWUPD_ERROR_INVALID_DATA,
521
89
                    "constant FuStructUf2.magic_end was not valid, "
522
89
                    "expected 0x%x and got 0x%x",
523
89
                    (guint) 0x0AB16F30,
524
89
                    (guint) fu_struct_uf2_get_magic_end(st));
525
89
        return FALSE;
526
89
    }
527
1.12k
    return TRUE;
528
1.20k
}
529
static gboolean
530
fu_struct_uf2_parse_internal(FuStructUf2 *st, GError **error)
531
1.29k
{
532
1.29k
    if (g_log_get_debug_enabled()) {
533
0
        g_autofree gchar *str = fu_struct_uf2_to_string(st);
534
0
        g_debug("%s", str);
535
0
    }
536
1.29k
    if (!fu_struct_uf2_validate_internal(st, error))
537
177
        return FALSE;
538
1.12k
    return TRUE;
539
1.29k
}
540
541
/**
542
 * fu_struct_uf2_parse: (skip):
543
 **/
544
FuStructUf2 *
545
fu_struct_uf2_parse(const guint8 *buf, gsize bufsz, gsize offset, GError **error)
546
1.34k
{
547
1.34k
    g_autoptr(FuStructUf2) st = fu_struct_uf2_new_internal();
548
1.34k
    g_return_val_if_fail(buf != NULL, NULL);
549
1.34k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
550
1.34k
    if (!fu_memchk_read(bufsz, offset, 512, error)) {
551
43
        g_prefix_error_literal(error, "invalid struct FuStructUf2: ");
552
43
        return NULL;
553
43
    }
554
1.29k
    st->buf = g_byte_array_new();
555
1.29k
    g_byte_array_append(st->buf, buf + offset, 512);
556
1.29k
    if (!fu_struct_uf2_parse_internal(st, error))
557
177
        return NULL;
558
1.12k
    return g_steal_pointer(&st);
559
1.29k
}