Coverage Report

Created: 2026-01-09 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/plugins/bcm57xx/fu-bcm57xx-common.c
Line
Count
Source
1
/*
2
 * Copyright 2018 Evan Lojewski
3
 * Copyright 2020 Richard Hughes <richard@hughsie.com>
4
 *
5
 * SPDX-License-Identifier: LGPL-2.1-or-later
6
 */
7
8
#include "config.h"
9
10
#include <string.h>
11
12
#include "fu-bcm57xx-common.h"
13
14
gboolean
15
fu_bcm57xx_verify_crc(GInputStream *stream, GError **error)
16
3.09k
{
17
3.09k
  guint32 crc_actual = 0xFFFFFFFF;
18
3.09k
  guint32 crc_file = 0;
19
3.09k
  gsize streamsz = 0;
20
3.09k
  g_autoptr(GInputStream) stream_tmp = NULL;
21
22
  /* expected */
23
3.09k
  if (!fu_input_stream_size(stream, &streamsz, error))
24
0
    return FALSE;
25
3.09k
  if (streamsz < sizeof(guint32)) {
26
2
    g_set_error_literal(error,
27
2
            FWUPD_ERROR,
28
2
            FWUPD_ERROR_INVALID_DATA,
29
2
            "image is too small for CRC");
30
2
    return FALSE;
31
2
  }
32
3.09k
  if (!fu_input_stream_read_u32(stream,
33
3.09k
              streamsz - sizeof(guint32),
34
3.09k
              &crc_file,
35
3.09k
              G_LITTLE_ENDIAN,
36
3.09k
              error))
37
0
    return FALSE;
38
39
  /* reality */
40
3.09k
  stream_tmp = fu_partial_input_stream_new(stream, 0, streamsz - sizeof(guint32), error);
41
3.09k
  if (stream_tmp == NULL)
42
0
    return FALSE;
43
3.09k
  if (!fu_input_stream_compute_crc32(stream_tmp,
44
3.09k
             FU_CRC_KIND_B32_STANDARD,
45
3.09k
             &crc_actual,
46
3.09k
             error))
47
0
    return FALSE;
48
3.09k
  if (crc_actual != crc_file) {
49
724
    g_set_error(error,
50
724
          FWUPD_ERROR,
51
724
          FWUPD_ERROR_NOT_SUPPORTED,
52
724
          "invalid CRC, expected 0x%08x got: 0x%08x",
53
724
          (guint)crc_file,
54
724
          (guint)crc_actual);
55
724
    return FALSE;
56
724
  }
57
58
  /* success */
59
2.37k
  return TRUE;
60
3.09k
}
61
62
gboolean
63
fu_bcm57xx_verify_magic(GInputStream *stream, gsize offset, GError **error)
64
2.57k
{
65
2.57k
  guint32 magic = 0;
66
67
  /* hardcoded value */
68
2.57k
  if (!fu_input_stream_read_u32(stream, offset, &magic, G_BIG_ENDIAN, error))
69
118
    return FALSE;
70
2.45k
  if (magic != BCM_NVRAM_MAGIC) {
71
62
    g_set_error(error,
72
62
          FWUPD_ERROR,
73
62
          FWUPD_ERROR_NOT_SUPPORTED,
74
62
          "invalid magic, got: 0x%x",
75
62
          (guint)magic);
76
62
    return FALSE;
77
62
  }
78
79
  /* success */
80
2.39k
  return TRUE;
81
2.45k
}
82
83
void
84
fu_bcm57xx_veritem_free(FuBcm57xxVeritem *veritem)
85
74
{
86
74
  g_free(veritem->branch);
87
74
  g_free(veritem->version);
88
74
  g_free(veritem);
89
74
}
90
91
FuBcm57xxVeritem *
92
fu_bcm57xx_veritem_new(const guint8 *buf, gsize bufsz)
93
74
{
94
74
  g_autofree gchar *tmp = NULL;
95
74
  g_autoptr(FuBcm57xxVeritem) veritem = g_new0(FuBcm57xxVeritem, 1);
96
74
  struct {
97
74
    const gchar *prefix;
98
74
    const gchar *branch;
99
74
    FwupdVersionFormat verfmt;
100
74
  } data[] = {{"5719-v", BCM_FW_BRANCH_UNKNOWN, FWUPD_VERSION_FORMAT_PAIR},
101
74
        {"stage1-", BCM_FW_BRANCH_OSS_FIRMWARE, FWUPD_VERSION_FORMAT_TRIPLET},
102
74
        {NULL, NULL, 0}};
103
104
  /* do not assume this is NUL terminated */
105
74
  tmp = g_strndup((const gchar *)buf, bufsz);
106
74
  if (tmp == NULL || tmp[0] == '\0')
107
3
    return NULL;
108
109
  /* use prefix to define object */
110
198
  for (guint i = 0; data[i].prefix != NULL; i++) {
111
136
    if (g_str_has_prefix(tmp, data[i].prefix)) {
112
9
      veritem->version = g_strdup(tmp + strlen(data[i].prefix));
113
9
      veritem->branch = g_strdup(data[i].branch);
114
9
      veritem->verfmt = data[i].verfmt;
115
9
      return g_steal_pointer(&veritem);
116
9
    }
117
136
  }
118
62
  veritem->verfmt = FWUPD_VERSION_FORMAT_UNKNOWN;
119
62
  veritem->version = g_strdup(tmp);
120
62
  return g_steal_pointer(&veritem);
121
71
}