Coverage Report

Created: 2026-01-25 06:22

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