Coverage Report

Created: 2025-12-14 06:56

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.02k
{
17
3.02k
  guint32 crc_actual = 0xFFFFFFFF;
18
3.02k
  guint32 crc_file = 0;
19
3.02k
  gsize streamsz = 0;
20
3.02k
  g_autoptr(GInputStream) stream_tmp = NULL;
21
22
  /* expected */
23
3.02k
  if (!fu_input_stream_size(stream, &streamsz, error))
24
0
    return FALSE;
25
3.02k
  if (streamsz < sizeof(guint32)) {
26
1
    g_set_error_literal(error,
27
1
            FWUPD_ERROR,
28
1
            FWUPD_ERROR_INVALID_DATA,
29
1
            "image is too small for CRC");
30
1
    return FALSE;
31
1
  }
32
3.02k
  if (!fu_input_stream_read_u32(stream,
33
3.02k
              streamsz - sizeof(guint32),
34
3.02k
              &crc_file,
35
3.02k
              G_LITTLE_ENDIAN,
36
3.02k
              error))
37
0
    return FALSE;
38
39
  /* reality */
40
3.02k
  stream_tmp = fu_partial_input_stream_new(stream, 0, streamsz - sizeof(guint32), error);
41
3.02k
  if (stream_tmp == NULL)
42
0
    return FALSE;
43
3.02k
  if (!fu_input_stream_compute_crc32(stream_tmp,
44
3.02k
             FU_CRC_KIND_B32_STANDARD,
45
3.02k
             &crc_actual,
46
3.02k
             error))
47
0
    return FALSE;
48
3.02k
  if (crc_actual != crc_file) {
49
725
    g_set_error(error,
50
725
          FWUPD_ERROR,
51
725
          FWUPD_ERROR_NOT_SUPPORTED,
52
725
          "invalid CRC, expected 0x%08x got: 0x%08x",
53
725
          (guint)crc_file,
54
725
          (guint)crc_actual);
55
725
    return FALSE;
56
725
  }
57
58
  /* success */
59
2.30k
  return TRUE;
60
3.02k
}
61
62
gboolean
63
fu_bcm57xx_verify_magic(GInputStream *stream, gsize offset, GError **error)
64
2.51k
{
65
2.51k
  guint32 magic = 0;
66
67
  /* hardcoded value */
68
2.51k
  if (!fu_input_stream_read_u32(stream, offset, &magic, G_BIG_ENDIAN, error))
69
112
    return FALSE;
70
2.40k
  if (magic != BCM_NVRAM_MAGIC) {
71
57
    g_set_error(error,
72
57
          FWUPD_ERROR,
73
57
          FWUPD_ERROR_NOT_SUPPORTED,
74
57
          "invalid magic, got: 0x%x",
75
57
          (guint)magic);
76
57
    return FALSE;
77
57
  }
78
79
  /* success */
80
2.34k
  return TRUE;
81
2.40k
}
82
83
void
84
fu_bcm57xx_veritem_free(FuBcm57xxVeritem *veritem)
85
72
{
86
72
  g_free(veritem->branch);
87
72
  g_free(veritem->version);
88
72
  g_free(veritem);
89
72
}
90
91
FuBcm57xxVeritem *
92
fu_bcm57xx_veritem_new(const guint8 *buf, gsize bufsz)
93
72
{
94
72
  g_autofree gchar *tmp = NULL;
95
72
  g_autoptr(FuBcm57xxVeritem) veritem = g_new0(FuBcm57xxVeritem, 1);
96
72
  struct {
97
72
    const gchar *prefix;
98
72
    const gchar *branch;
99
72
    FwupdVersionFormat verfmt;
100
72
  } data[] = {{"5719-v", BCM_FW_BRANCH_UNKNOWN, FWUPD_VERSION_FORMAT_PAIR},
101
72
        {"stage1-", BCM_FW_BRANCH_OSS_FIRMWARE, FWUPD_VERSION_FORMAT_TRIPLET},
102
72
        {NULL, NULL, 0}};
103
104
  /* do not assume this is NUL terminated */
105
72
  tmp = g_strndup((const gchar *)buf, bufsz);
106
72
  if (tmp == NULL || tmp[0] == '\0')
107
3
    return NULL;
108
109
  /* use prefix to define object */
110
192
  for (guint i = 0; data[i].prefix != NULL; i++) {
111
132
    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
132
  }
118
60
  veritem->verfmt = FWUPD_VERSION_FORMAT_UNKNOWN;
119
60
  veritem->version = g_strdup(tmp);
120
60
  return g_steal_pointer(&veritem);
121
69
}