Coverage Report

Created: 2026-07-16 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/plugins/acpi-phat/fu-acpi-phat-version-record.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 "fu-acpi-phat-struct.h"
10
#include "fu-acpi-phat-version-element.h"
11
#include "fu-acpi-phat-version-record.h"
12
#include "fu-acpi-phat.h"
13
14
struct _FuAcpiPhatVersionRecord {
15
  FuFirmware parent_instance;
16
};
17
18
15.8k
G_DEFINE_TYPE(FuAcpiPhatVersionRecord, fu_acpi_phat_version_record, FU_TYPE_FIRMWARE)
19
15.8k
20
15.8k
static gboolean
21
15.8k
fu_acpi_phat_version_record_parse(FuFirmware *firmware,
22
15.8k
          FuInputStream *stream,
23
15.8k
          FuFirmwareParseFlags flags,
24
15.8k
          GError **error)
25
15.8k
{
26
15.7k
  gsize offset = 0;
27
15.7k
  guint32 record_count = 0;
28
15.7k
  g_autoptr(FuStructAcpiPhatVersionRecord) st = NULL;
29
30
15.7k
  st = fu_struct_acpi_phat_version_record_parse_stream(stream, offset, error);
31
15.7k
  if (st == NULL)
32
18
    return FALSE;
33
15.7k
  record_count = fu_struct_acpi_phat_version_record_get_record_count(st);
34
35.2k
  for (guint32 i = 0; i < record_count; i++) {
35
19.6k
    g_autoptr(FuFirmware) firmware_tmp = fu_acpi_phat_version_element_new();
36
19.6k
    g_autoptr(FuInputStream) stream_tmp = NULL;
37
19.6k
    stream_tmp = fu_partial_input_stream_new(stream,
38
19.6k
               offset + st->buf->len,
39
19.6k
               FU_STRUCT_ACPI_PHAT_VERSION_ELEMENT_SIZE,
40
19.6k
               error);
41
19.6k
    if (stream_tmp == NULL)
42
167
      return FALSE;
43
19.5k
    fu_firmware_set_offset(firmware_tmp, offset + st->buf->len);
44
19.5k
    if (!fu_firmware_parse_stream(firmware_tmp,
45
19.5k
                stream_tmp,
46
19.5k
                0x0,
47
19.5k
                flags | FU_FIRMWARE_PARSE_FLAG_NO_SEARCH,
48
19.5k
                error))
49
0
      return FALSE;
50
19.5k
    if (!fu_firmware_add_image(firmware, firmware_tmp, error))
51
4
      return FALSE;
52
19.5k
    if (!fu_size_checked_inc(&offset, fu_firmware_get_size(firmware_tmp), error))
53
0
      return FALSE;
54
19.5k
  }
55
15.6k
  return TRUE;
56
15.7k
}
57
58
static GByteArray *
59
fu_acpi_phat_version_record_write(FuFirmware *firmware, GError **error)
60
6.83k
{
61
6.83k
  g_autoptr(GByteArray) buf2 = g_byte_array_new();
62
6.83k
  g_autoptr(FuStructAcpiPhatVersionRecord) st = fu_struct_acpi_phat_version_record_new();
63
6.83k
  g_autoptr(GPtrArray) images = fu_firmware_get_images(firmware);
64
65
  /* write each element so we get the image size */
66
9.36k
  for (guint i = 0; i < images->len; i++) {
67
2.52k
    FuFirmware *img = g_ptr_array_index(images, i);
68
2.52k
    g_autoptr(GBytes) blob = fu_firmware_write(img, error);
69
2.52k
    if (blob == NULL)
70
0
      return NULL;
71
2.52k
    fu_byte_array_append_bytes(buf2, blob);
72
2.52k
  }
73
74
  /* data record */
75
6.83k
  fu_struct_acpi_phat_version_record_set_rcdlen(st, st->buf->len + buf2->len);
76
6.83k
  fu_struct_acpi_phat_version_record_set_version(st, fu_firmware_get_version_raw(firmware));
77
6.83k
  fu_struct_acpi_phat_version_record_set_record_count(st, images->len);
78
79
  /* element data */
80
6.83k
  g_byte_array_append(st->buf, buf2->data, buf2->len);
81
6.83k
  return g_steal_pointer(&st->buf);
82
6.83k
}
83
84
static void
85
fu_acpi_phat_version_record_init(FuAcpiPhatVersionRecord *self)
86
15.8k
{
87
15.8k
  fu_firmware_add_flag(FU_FIRMWARE(self), FU_FIRMWARE_FLAG_NO_AUTO_DETECTION);
88
15.8k
}
89
90
static void
91
fu_acpi_phat_version_record_class_init(FuAcpiPhatVersionRecordClass *klass)
92
1
{
93
1
  FuFirmwareClass *firmware_class = FU_FIRMWARE_CLASS(klass);
94
1
  fu_firmware_add_image_gtype(firmware_class, FU_TYPE_ACPI_PHAT_VERSION_ELEMENT);
95
1
  firmware_class->parse = fu_acpi_phat_version_record_parse;
96
1
  firmware_class->write = fu_acpi_phat_version_record_write;
97
1
  fu_firmware_set_size_max(firmware_class, 1 * FU_MB);
98
1
  fu_firmware_set_images_max(firmware_class, 2000);
99
1
}
100
101
FuFirmware *
102
fu_acpi_phat_version_record_new(void)
103
15.8k
{
104
15.8k
  return FU_FIRMWARE(g_object_new(FU_TYPE_ACPI_PHAT_VERSION_RECORD, NULL));
105
15.8k
}