Coverage Report

Created: 2025-07-01 07:09

/work/fu-edid-struct.c
Line
Count
Source (jump to first uncovered line)
1
/* auto-generated, do not modify */
2
#include "config.h"
3
4
#include "fu-edid-struct.h"
5
#include "fu-byte-array.h"
6
#include "fu-mem-private.h"
7
#include "fu-string.h"
8
9
#ifdef G_LOG_DOMAIN
10
  #undef G_LOG_DOMAIN
11
#endif
12
0
#define G_LOG_DOMAIN "FuStruct"
13
14
static const gchar *
15
fu_edid_descriptor_tag_to_string(FuEdidDescriptorTag val)
16
0
{
17
0
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_PRODUCT_SERIAL_NUMBER)
18
0
        return "display-product-serial-number";
19
0
    if (val == FU_EDID_DESCRIPTOR_TAG_ALPHANUMERIC_DATA_STRING)
20
0
        return "alphanumeric-data-string";
21
0
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_RANGE_LIMITS)
22
0
        return "display-range-limits";
23
0
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_PRODUCT_NAME)
24
0
        return "display-product-name";
25
0
    if (val == FU_EDID_DESCRIPTOR_TAG_COLOR_POINT_DATA)
26
0
        return "color-point-data";
27
0
    if (val == FU_EDID_DESCRIPTOR_TAG_STANDARD_TIMING_IDENTIFICATIONS)
28
0
        return "standard-timing-identifications";
29
0
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_COLOR_MANAGEMENT_DATA)
30
0
        return "display-color-management-data";
31
0
    if (val == FU_EDID_DESCRIPTOR_TAG_CVT_TIMING_CODES)
32
0
        return "cvt-timing-codes";
33
0
    if (val == FU_EDID_DESCRIPTOR_TAG_ESTABLISHED_TIMINGS)
34
0
        return "established-timings";
35
0
    if (val == FU_EDID_DESCRIPTOR_TAG_DUMMY_DESCRIPTOR)
36
0
        return "dummy-descriptor";
37
0
    return NULL;
38
0
}
39
/* getters */
40
/**
41
 * fu_struct_edid_descriptor_get_kind: (skip):
42
 **/
43
guint16
44
fu_struct_edid_descriptor_get_kind(const FuStructEdidDescriptor *st)
45
1.05k
{
46
1.05k
    g_return_val_if_fail(st != NULL, 0x0);
47
1.05k
    return fu_memread_uint16(st->data + 0, G_LITTLE_ENDIAN);
48
1.05k
}
49
/**
50
 * fu_struct_edid_descriptor_get_subkind: (skip):
51
 **/
52
guint8
53
fu_struct_edid_descriptor_get_subkind(const FuStructEdidDescriptor *st)
54
628
{
55
628
    g_return_val_if_fail(st != NULL, 0x0);
56
628
    return st->data[2];
57
628
}
58
/**
59
 * fu_struct_edid_descriptor_get_tag: (skip):
60
 **/
61
FuEdidDescriptorTag
62
fu_struct_edid_descriptor_get_tag(const FuStructEdidDescriptor *st)
63
1.46k
{
64
1.46k
    g_return_val_if_fail(st != NULL, 0x0);
65
1.46k
    return st->data[3];
66
1.46k
}
67
/**
68
 * fu_struct_edid_descriptor_get_data: (skip):
69
 **/
70
const guint8 *
71
fu_struct_edid_descriptor_get_data(const FuStructEdidDescriptor *st, gsize *bufsz)
72
557
{
73
557
    g_return_val_if_fail(st != NULL, NULL);
74
557
    if (bufsz != NULL)
75
557
        *bufsz = 13;
76
557
    return st->data + 5;
77
557
}
78
79
/* setters */
80
/**
81
 * fu_struct_edid_descriptor_set_kind: (skip):
82
 **/
83
void
84
fu_struct_edid_descriptor_set_kind(FuStructEdidDescriptor *st, guint16 value)
85
0
{
86
0
    g_return_if_fail(st != NULL);
87
0
    fu_memwrite_uint16(st->data + 0, value, G_LITTLE_ENDIAN);
88
0
}
89
/**
90
 * fu_struct_edid_descriptor_set_subkind: (skip):
91
 **/
92
void
93
fu_struct_edid_descriptor_set_subkind(FuStructEdidDescriptor *st, guint8 value)
94
0
{
95
0
    g_return_if_fail(st != NULL);
96
0
    st->data[2] = value;
97
0
}
98
/**
99
 * fu_struct_edid_descriptor_set_tag: (skip):
100
 **/
101
void
102
fu_struct_edid_descriptor_set_tag(FuStructEdidDescriptor *st, FuEdidDescriptorTag value)
103
290
{
104
290
    g_return_if_fail(st != NULL);
105
290
    st->data[3] = value;
106
290
}
107
/**
108
 * fu_struct_edid_descriptor_set_data: (skip):
109
 **/
110
gboolean
111
fu_struct_edid_descriptor_set_data(FuStructEdidDescriptor *st, const guint8 *buf, gsize bufsz, GError **error)
112
290
{
113
290
    g_return_val_if_fail(st != NULL, FALSE);
114
290
    g_return_val_if_fail(buf != NULL, FALSE);
115
290
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
116
290
    return fu_memcpy_safe(st->data, st->len, 5, buf, bufsz, 0x0, bufsz, error);
117
290
}
118
/**
119
 * fu_struct_edid_descriptor_new: (skip):
120
 **/
121
FuStructEdidDescriptor *
122
fu_struct_edid_descriptor_new(void)
123
290
{
124
290
    FuStructEdidDescriptor *st = g_byte_array_sized_new(18);
125
290
    fu_byte_array_set_size(st, 18, 0x0);
126
290
    return st;
127
290
}
128
/**
129
 * fu_struct_edid_descriptor_to_string: (skip):
130
 **/
131
static gchar *
132
fu_struct_edid_descriptor_to_string(const FuStructEdidDescriptor *st)
133
0
{
134
0
    g_autoptr(GString) str = g_string_new("FuStructEdidDescriptor:\n");
135
0
    g_return_val_if_fail(st != NULL, NULL);
136
0
    g_string_append_printf(str, "  kind: 0x%x\n",
137
0
                           (guint) fu_struct_edid_descriptor_get_kind(st));
138
0
    g_string_append_printf(str, "  subkind: 0x%x\n",
139
0
                           (guint) fu_struct_edid_descriptor_get_subkind(st));
140
0
    {
141
0
        const gchar *tmp = fu_edid_descriptor_tag_to_string(fu_struct_edid_descriptor_get_tag(st));
142
0
        if (tmp != NULL) {
143
0
            g_string_append_printf(str, "  tag: 0x%x [%s]\n", (guint) fu_struct_edid_descriptor_get_tag(st), tmp);
144
0
        } else {
145
0
            g_string_append_printf(str, "  tag: 0x%x\n", (guint) fu_struct_edid_descriptor_get_tag(st));
146
0
        }
147
0
    }
148
0
    {
149
0
        gsize bufsz = 0;
150
0
        const guint8 *buf = fu_struct_edid_descriptor_get_data(st, &bufsz);
151
0
        g_autoptr(GString) tmp = g_string_new(NULL);
152
0
        for (gsize i = 0; i < bufsz; i++)
153
0
            g_string_append_printf(tmp, "%02X", buf[i]);
154
0
        g_string_append_printf(str, "  data: 0x%s\n", tmp->str);
155
0
    }
156
0
    if (str->len > 0)
157
0
        g_string_set_size(str, str->len - 1);
158
0
    return g_string_free(g_steal_pointer(&str), FALSE);
159
0
}
160
static gboolean
161
fu_struct_edid_descriptor_validate_internal(FuStructEdidDescriptor *st, GError **error)
162
1.05k
{
163
1.05k
    g_return_val_if_fail(st != NULL, FALSE);
164
1.05k
    return TRUE;
165
1.05k
}
166
static gboolean
167
fu_struct_edid_descriptor_parse_internal(FuStructEdidDescriptor *st, GError **error)
168
1.05k
{
169
1.05k
    if (!fu_struct_edid_descriptor_validate_internal(st, error))
170
0
        return FALSE;
171
1.05k
    if (g_getenv("FWUPD_VERBOSE") != NULL) {
172
0
        g_autofree gchar *str = fu_struct_edid_descriptor_to_string(st);
173
0
        g_debug("%s", str);
174
0
    }
175
1.05k
    return TRUE;
176
1.05k
}
177
/**
178
 * fu_struct_edid_descriptor_parse_stream: (skip):
179
 **/
180
FuStructEdidDescriptor *
181
fu_struct_edid_descriptor_parse_stream(GInputStream *stream, gsize offset, GError **error)
182
1.05k
{
183
1.05k
    g_autoptr(GByteArray) st = NULL;
184
1.05k
    st = fu_input_stream_read_byte_array(stream, offset, 18, NULL, error);
185
1.05k
    if (st == NULL) {
186
0
        g_prefix_error(error, "FuStructEdidDescriptor failed read of 0x%x: ", (guint) 18);
187
0
        return NULL;
188
0
    }
189
1.05k
    if (st->len != 18) {
190
0
        g_set_error(error,
191
0
                    FWUPD_ERROR,
192
0
                    FWUPD_ERROR_INVALID_DATA,
193
0
                    "FuStructEdidDescriptor requested 0x%x and got 0x%x",
194
0
                    (guint) 18,
195
0
                    (guint) st->len);
196
0
        return NULL;
197
0
    }
198
1.05k
    if (!fu_struct_edid_descriptor_parse_internal(st, error))
199
0
        return NULL;
200
1.05k
    return g_steal_pointer(&st);
201
1.05k
}
202
/* getters */
203
/**
204
 * fu_struct_edid_get_manufacturer_name: (skip):
205
 **/
206
const guint8 *
207
fu_struct_edid_get_manufacturer_name(const FuStructEdid *st, gsize *bufsz)
208
263
{
209
263
    g_return_val_if_fail(st != NULL, NULL);
210
263
    if (bufsz != NULL)
211
0
        *bufsz = 2;
212
263
    return st->data + 8;
213
263
}
214
/**
215
 * fu_struct_edid_get_product_code: (skip):
216
 **/
217
guint16
218
fu_struct_edid_get_product_code(const FuStructEdid *st)
219
263
{
220
263
    g_return_val_if_fail(st != NULL, 0x0);
221
263
    return fu_memread_uint16(st->data + 10, G_LITTLE_ENDIAN);
222
263
}
223
/**
224
 * fu_struct_edid_get_serial_number: (skip):
225
 **/
226
guint32
227
fu_struct_edid_get_serial_number(const FuStructEdid *st)
228
520
{
229
520
    g_return_val_if_fail(st != NULL, 0x0);
230
520
    return fu_memread_uint32(st->data + 12, G_LITTLE_ENDIAN);
231
520
}
232
/**
233
 * fu_struct_edid_get_week_of_manufacture: (skip):
234
 **/
235
guint8
236
fu_struct_edid_get_week_of_manufacture(const FuStructEdid *st)
237
0
{
238
0
    g_return_val_if_fail(st != NULL, 0x0);
239
0
    return st->data[16];
240
0
}
241
/**
242
 * fu_struct_edid_get_year_of_manufacture: (skip):
243
 **/
244
guint8
245
fu_struct_edid_get_year_of_manufacture(const FuStructEdid *st)
246
0
{
247
0
    g_return_val_if_fail(st != NULL, 0x0);
248
0
    return st->data[17];
249
0
}
250
/**
251
 * fu_struct_edid_get_edid_version_number: (skip):
252
 **/
253
static guint8
254
fu_struct_edid_get_edid_version_number(const FuStructEdid *st)
255
272
{
256
272
    g_return_val_if_fail(st != NULL, 0x0);
257
272
    return st->data[18];
258
272
}
259
/**
260
 * fu_struct_edid_get_revision_number: (skip):
261
 **/
262
guint8
263
fu_struct_edid_get_revision_number(const FuStructEdid *st)
264
0
{
265
0
    g_return_val_if_fail(st != NULL, 0x0);
266
0
    return st->data[19];
267
0
}
268
/**
269
 * fu_struct_edid_get_data_blocks: (skip):
270
 **/
271
const guint8 *
272
fu_struct_edid_get_data_blocks(const FuStructEdid *st, gsize *bufsz)
273
0
{
274
0
    g_return_val_if_fail(st != NULL, NULL);
275
0
    if (bufsz != NULL)
276
0
        *bufsz = 72;
277
0
    return st->data + 54;
278
0
}
279
/**
280
 * fu_struct_edid_get_extension_block_count: (skip):
281
 **/
282
guint8
283
fu_struct_edid_get_extension_block_count(const FuStructEdid *st)
284
0
{
285
0
    g_return_val_if_fail(st != NULL, 0x0);
286
0
    return st->data[126];
287
0
}
288
/**
289
 * fu_struct_edid_get_checksum: (skip):
290
 **/
291
guint8
292
fu_struct_edid_get_checksum(const FuStructEdid *st)
293
0
{
294
0
    g_return_val_if_fail(st != NULL, 0x0);
295
0
    return st->data[127];
296
0
}
297
298
/* setters */
299
/**
300
 * fu_struct_edid_set_manufacturer_name: (skip):
301
 **/
302
gboolean
303
fu_struct_edid_set_manufacturer_name(FuStructEdid *st, const guint8 *buf, gsize bufsz, GError **error)
304
0
{
305
0
    g_return_val_if_fail(st != NULL, FALSE);
306
0
    g_return_val_if_fail(buf != NULL, FALSE);
307
0
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
308
0
    return fu_memcpy_safe(st->data, st->len, 8, buf, bufsz, 0x0, bufsz, error);
309
0
}
310
/**
311
 * fu_struct_edid_set_product_code: (skip):
312
 **/
313
void
314
fu_struct_edid_set_product_code(FuStructEdid *st, guint16 value)
315
263
{
316
263
    g_return_if_fail(st != NULL);
317
263
    fu_memwrite_uint16(st->data + 10, value, G_LITTLE_ENDIAN);
318
263
}
319
/**
320
 * fu_struct_edid_set_serial_number: (skip):
321
 **/
322
void
323
fu_struct_edid_set_serial_number(FuStructEdid *st, guint32 value)
324
121
{
325
121
    g_return_if_fail(st != NULL);
326
121
    fu_memwrite_uint32(st->data + 12, value, G_LITTLE_ENDIAN);
327
121
}
328
/**
329
 * fu_struct_edid_set_week_of_manufacture: (skip):
330
 **/
331
void
332
fu_struct_edid_set_week_of_manufacture(FuStructEdid *st, guint8 value)
333
0
{
334
0
    g_return_if_fail(st != NULL);
335
0
    st->data[16] = value;
336
0
}
337
/**
338
 * fu_struct_edid_set_year_of_manufacture: (skip):
339
 **/
340
void
341
fu_struct_edid_set_year_of_manufacture(FuStructEdid *st, guint8 value)
342
0
{
343
0
    g_return_if_fail(st != NULL);
344
0
    st->data[17] = value;
345
0
}
346
/**
347
 * fu_struct_edid_set_edid_version_number: (skip):
348
 **/
349
static void
350
fu_struct_edid_set_edid_version_number(FuStructEdid *st, guint8 value)
351
263
{
352
263
    g_return_if_fail(st != NULL);
353
263
    st->data[18] = value;
354
263
}
355
/**
356
 * fu_struct_edid_set_revision_number: (skip):
357
 **/
358
void
359
fu_struct_edid_set_revision_number(FuStructEdid *st, guint8 value)
360
263
{
361
263
    g_return_if_fail(st != NULL);
362
263
    st->data[19] = value;
363
263
}
364
/**
365
 * fu_struct_edid_set_data_blocks: (skip):
366
 **/
367
gboolean
368
fu_struct_edid_set_data_blocks(FuStructEdid *st, const guint8 *buf, gsize bufsz, GError **error)
369
0
{
370
0
    g_return_val_if_fail(st != NULL, FALSE);
371
0
    g_return_val_if_fail(buf != NULL, FALSE);
372
0
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
373
0
    return fu_memcpy_safe(st->data, st->len, 54, buf, bufsz, 0x0, bufsz, error);
374
0
}
375
/**
376
 * fu_struct_edid_set_extension_block_count: (skip):
377
 **/
378
void
379
fu_struct_edid_set_extension_block_count(FuStructEdid *st, guint8 value)
380
0
{
381
0
    g_return_if_fail(st != NULL);
382
0
    st->data[126] = value;
383
0
}
384
/**
385
 * fu_struct_edid_set_checksum: (skip):
386
 **/
387
void
388
fu_struct_edid_set_checksum(FuStructEdid *st, guint8 value)
389
0
{
390
0
    g_return_if_fail(st != NULL);
391
0
    st->data[127] = value;
392
0
}
393
/**
394
 * fu_struct_edid_new: (skip):
395
 **/
396
FuStructEdid *
397
fu_struct_edid_new(void)
398
263
{
399
263
    FuStructEdid *st = g_byte_array_sized_new(128);
400
263
    fu_byte_array_set_size(st, 128, 0x0);
401
263
    memcpy(st->data + 0x0, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8); /* nocheck:blocked */
402
263
    fu_struct_edid_set_edid_version_number(st, 0x1);
403
263
    fu_struct_edid_set_revision_number(st, 0x3);
404
263
    return st;
405
263
}
406
/**
407
 * fu_struct_edid_to_string: (skip):
408
 **/
409
static gchar *
410
fu_struct_edid_to_string(const FuStructEdid *st)
411
0
{
412
0
    g_autoptr(GString) str = g_string_new("FuStructEdid:\n");
413
0
    g_return_val_if_fail(st != NULL, NULL);
414
0
    {
415
0
        gsize bufsz = 0;
416
0
        const guint8 *buf = fu_struct_edid_get_manufacturer_name(st, &bufsz);
417
0
        g_autoptr(GString) tmp = g_string_new(NULL);
418
0
        for (gsize i = 0; i < bufsz; i++)
419
0
            g_string_append_printf(tmp, "%02X", buf[i]);
420
0
        g_string_append_printf(str, "  manufacturer_name: 0x%s\n", tmp->str);
421
0
    }
422
0
    g_string_append_printf(str, "  product_code: 0x%x\n",
423
0
                           (guint) fu_struct_edid_get_product_code(st));
424
0
    g_string_append_printf(str, "  serial_number: 0x%x\n",
425
0
                           (guint) fu_struct_edid_get_serial_number(st));
426
0
    g_string_append_printf(str, "  week_of_manufacture: 0x%x\n",
427
0
                           (guint) fu_struct_edid_get_week_of_manufacture(st));
428
0
    g_string_append_printf(str, "  year_of_manufacture: 0x%x\n",
429
0
                           (guint) fu_struct_edid_get_year_of_manufacture(st));
430
0
    g_string_append_printf(str, "  revision_number: 0x%x\n",
431
0
                           (guint) fu_struct_edid_get_revision_number(st));
432
0
    {
433
0
        gsize bufsz = 0;
434
0
        const guint8 *buf = fu_struct_edid_get_data_blocks(st, &bufsz);
435
0
        g_autoptr(GString) tmp = g_string_new(NULL);
436
0
        for (gsize i = 0; i < bufsz; i++)
437
0
            g_string_append_printf(tmp, "%02X", buf[i]);
438
0
        g_string_append_printf(str, "  data_blocks: 0x%s\n", tmp->str);
439
0
    }
440
0
    g_string_append_printf(str, "  extension_block_count: 0x%x\n",
441
0
                           (guint) fu_struct_edid_get_extension_block_count(st));
442
0
    g_string_append_printf(str, "  checksum: 0x%x\n",
443
0
                           (guint) fu_struct_edid_get_checksum(st));
444
0
    if (str->len > 0)
445
0
        g_string_set_size(str, str->len - 1);
446
0
    return g_string_free(g_steal_pointer(&str), FALSE);
447
0
}
448
static gboolean
449
fu_struct_edid_validate_internal(FuStructEdid *st, GError **error)
450
371
{
451
371
    g_return_val_if_fail(st != NULL, FALSE);
452
371
    if (memcmp(st->data + 0, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8) != 0) {
453
99
        g_set_error_literal(error,
454
99
                            FWUPD_ERROR,
455
99
                            FWUPD_ERROR_INVALID_DATA,
456
99
                            "constant FuStructEdid.header was not valid");
457
99
        return FALSE;
458
99
    }
459
272
    if (fu_struct_edid_get_edid_version_number(st) != 0x1) {
460
9
        g_set_error_literal(error,
461
9
                            FWUPD_ERROR,
462
9
                            FWUPD_ERROR_INVALID_DATA,
463
9
                            "constant FuStructEdid.edid_version_number was not valid");
464
9
        return FALSE;
465
9
    }
466
263
    return TRUE;
467
272
}
468
static gboolean
469
fu_struct_edid_parse_internal(FuStructEdid *st, GError **error)
470
371
{
471
371
    if (!fu_struct_edid_validate_internal(st, error))
472
108
        return FALSE;
473
263
    if (g_getenv("FWUPD_VERBOSE") != NULL) {
474
0
        g_autofree gchar *str = fu_struct_edid_to_string(st);
475
0
        g_debug("%s", str);
476
0
    }
477
263
    return TRUE;
478
371
}
479
/**
480
 * fu_struct_edid_parse_stream: (skip):
481
 **/
482
FuStructEdid *
483
fu_struct_edid_parse_stream(GInputStream *stream, gsize offset, GError **error)
484
403
{
485
403
    g_autoptr(GByteArray) st = NULL;
486
403
    st = fu_input_stream_read_byte_array(stream, offset, 128, NULL, error);
487
403
    if (st == NULL) {
488
0
        g_prefix_error(error, "FuStructEdid failed read of 0x%x: ", (guint) 128);
489
0
        return NULL;
490
0
    }
491
403
    if (st->len != 128) {
492
32
        g_set_error(error,
493
32
                    FWUPD_ERROR,
494
32
                    FWUPD_ERROR_INVALID_DATA,
495
32
                    "FuStructEdid requested 0x%x and got 0x%x",
496
32
                    (guint) 128,
497
32
                    (guint) st->len);
498
32
        return NULL;
499
32
    }
500
371
    if (!fu_struct_edid_parse_internal(st, error))
501
108
        return NULL;
502
263
    return g_steal_pointer(&st);
503
371
}