mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-02 16:45:45 +00:00
Allow objects to deserialize to XML
This makes a lot more sense; we can parse a firmware and export the same XML we would use in a .builder.xml file. This allows us to two two things: * Check we can round trip from XML -> binary -> XML * Using a .builder.xml file we can check ->write() is endian safe
This commit is contained in:
parent
278c3998a5
commit
52441f28a4
@ -6,6 +6,7 @@ _fwupdtool_cmd_list=(
|
||||
'esp-unmount'
|
||||
'firmware-build'
|
||||
'firmware-convert'
|
||||
'firmware-export'
|
||||
'firmware-extract'
|
||||
'firmware-parse'
|
||||
'get-updates'
|
||||
|
@ -9,10 +9,11 @@
|
||||
#include <xmlb.h>
|
||||
|
||||
#include "fu-chunk.h"
|
||||
#include "fu-firmware.h"
|
||||
|
||||
void fu_chunk_add_string (FuChunk *self,
|
||||
guint idt,
|
||||
GString *str);
|
||||
void fu_chunk_export (FuChunk *self,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn);
|
||||
gboolean fu_chunk_build (FuChunk *self,
|
||||
XbNode *n,
|
||||
GError **error);
|
||||
|
@ -292,19 +292,23 @@ fu_chunk_bytes_new (GBytes *bytes)
|
||||
}
|
||||
|
||||
void
|
||||
fu_chunk_add_string (FuChunk *self, guint idt, GString *str)
|
||||
fu_chunk_export (FuChunk *self, FuFirmwareExportFlags flags, XbBuilderNode *bn)
|
||||
{
|
||||
fu_common_string_append_kv (str, idt, G_OBJECT_TYPE_NAME (self), NULL);
|
||||
fu_common_string_append_kx (str, idt + 1, "Index", self->idx);
|
||||
fu_common_string_append_kx (str, idt + 1, "Page", self->page);
|
||||
fu_common_string_append_kx (str, idt + 1, "Address", self->address);
|
||||
fu_xmlb_builder_insert_kx (bn, "idx", self->idx);
|
||||
fu_xmlb_builder_insert_kx (bn, "page", self->page);
|
||||
fu_xmlb_builder_insert_kx (bn, "addr", self->address);
|
||||
if (self->data != NULL) {
|
||||
g_autofree gchar *datastr = NULL;
|
||||
datastr = fu_common_strsafe ((const gchar *) self->data, MIN (self->data_sz, 16));
|
||||
if (datastr != NULL)
|
||||
fu_common_string_append_kv (str, idt + 1, "Data", datastr);
|
||||
g_autofree gchar *dataszstr = g_strdup_printf ("0x%x", (guint) self->data_sz);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA) {
|
||||
datastr = fu_common_strsafe ((const gchar *) self->data, MIN (self->data_sz, 16));
|
||||
} else {
|
||||
datastr = g_base64_encode (self->data, self->data_sz);
|
||||
}
|
||||
xb_builder_node_insert_text (bn, "data", datastr,
|
||||
"size", dataszstr,
|
||||
NULL);
|
||||
}
|
||||
fu_common_string_append_kx (str, idt + 1, "DataSz", self->data_sz);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -320,9 +324,15 @@ fu_chunk_add_string (FuChunk *self, guint idt, GString *str)
|
||||
gchar *
|
||||
fu_chunk_to_string (FuChunk *self)
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
fu_chunk_add_string (self, 0, str);
|
||||
return g_string_free (str, FALSE);
|
||||
g_autoptr(XbBuilderNode) bn = xb_builder_node_new ("chunk");
|
||||
fu_chunk_export (self, FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA, bn);
|
||||
return xb_builder_node_export (bn,
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_MULTILINE |
|
||||
#if LIBXMLB_CHECK_VERSION(0,2,2)
|
||||
XB_NODE_EXPORT_FLAG_COLLAPSE_EMPTY |
|
||||
#endif
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_INDENT,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,15 +348,19 @@ fu_chunk_to_string (FuChunk *self)
|
||||
gchar *
|
||||
fu_chunk_array_to_string (GPtrArray *chunks)
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
g_autoptr(XbBuilderNode) bn = xb_builder_node_new ("chunks");
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index (chunks, i);
|
||||
g_autofree gchar *tmp = fu_chunk_to_string (chk);
|
||||
g_string_append_printf (str, "%s\n", tmp);
|
||||
g_autoptr(XbBuilderNode) bc = xb_builder_node_insert (bn, "chunk", NULL);
|
||||
fu_chunk_export (chk, FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA, bc);
|
||||
}
|
||||
if (str->len > 0)
|
||||
g_string_truncate (str, str->len - 1);
|
||||
return g_string_free (str, FALSE);
|
||||
return xb_builder_node_export (bn,
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_MULTILINE |
|
||||
#if LIBXMLB_CHECK_VERSION(0,2,2)
|
||||
XB_NODE_EXPORT_FLAG_COLLAPSE_EMPTY |
|
||||
#endif
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_INDENT,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3276,3 +3276,59 @@ fu_common_align_up (gsize value, guint8 alignment)
|
||||
/* success */
|
||||
return value_new;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_xmlb_builder_insert_kv:
|
||||
* @bn: #JsonBuilder
|
||||
* @key: string key
|
||||
* @value: string value
|
||||
*
|
||||
* Convenience function to add an XML node with a string value. If @value is %NULL
|
||||
* then no member is added.
|
||||
*
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
void
|
||||
fu_xmlb_builder_insert_kv (XbBuilderNode *bn, const gchar *key, const gchar *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return;
|
||||
xb_builder_node_insert_text (bn, key, value, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_xmlb_builder_insert_kx:
|
||||
* @bn: #JsonBuilder
|
||||
* @key: string key
|
||||
* @value: integer value
|
||||
*
|
||||
* Convenience function to add an XML node with a integer value. If @value is 0
|
||||
* then no member is added.
|
||||
*
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
void
|
||||
fu_xmlb_builder_insert_kx (XbBuilderNode *bn, const gchar *key, guint64 value)
|
||||
{
|
||||
g_autofree gchar *value_hex = NULL;
|
||||
if (value == 0)
|
||||
return;
|
||||
value_hex = g_strdup_printf ("0x%x", (guint) value);
|
||||
xb_builder_node_insert_text (bn, key, value_hex, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_xmlb_builder_insert_kb:
|
||||
* @bn: #JsonBuilder
|
||||
* @key: string key
|
||||
* @value: boolean value
|
||||
*
|
||||
* Convenience function to add an XML node with a boolean value.
|
||||
*
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
void
|
||||
fu_xmlb_builder_insert_kb (XbBuilderNode *bn, const gchar *key, gboolean value)
|
||||
{
|
||||
xb_builder_node_insert_text (bn, key, value ? "true" : "false", NULL);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <xmlb.h>
|
||||
|
||||
#include "fu-volume.h"
|
||||
|
||||
@ -363,3 +364,13 @@ guint32 fu_common_crc32_full (const guint8 *buf,
|
||||
gchar *fu_common_uri_get_scheme (const gchar *uri);
|
||||
gsize fu_common_align_up (gsize value,
|
||||
guint8 alignment);
|
||||
|
||||
void fu_xmlb_builder_insert_kv (XbBuilderNode *bn,
|
||||
const gchar *key,
|
||||
const gchar *value);
|
||||
void fu_xmlb_builder_insert_kx (XbBuilderNode *bn,
|
||||
const gchar *key,
|
||||
guint64 value);
|
||||
void fu_xmlb_builder_insert_kb (XbBuilderNode *bn,
|
||||
const gchar *key,
|
||||
gboolean value);
|
||||
|
@ -34,14 +34,16 @@ G_DEFINE_TYPE_WITH_PRIVATE (FuDfuFirmware, fu_dfu_firmware, FU_TYPE_FIRMWARE)
|
||||
#define GET_PRIVATE(o) (fu_dfu_firmware_get_instance_private (o))
|
||||
|
||||
static void
|
||||
fu_dfu_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_dfu_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuDfuFirmware *self = FU_DFU_FIRMWARE (firmware);
|
||||
FuDfuFirmwarePrivate *priv = GET_PRIVATE (self);
|
||||
fu_common_string_append_kx (str, idt, "Vid", priv->vid);
|
||||
fu_common_string_append_kx (str, idt, "Pid", priv->pid);
|
||||
fu_common_string_append_kx (str, idt, "Release", priv->release);
|
||||
fu_common_string_append_kx (str, idt, "DfuVersion", priv->dfu_version);
|
||||
fu_xmlb_builder_insert_kx (bn, "vendor", priv->vid);
|
||||
fu_xmlb_builder_insert_kx (bn, "product", priv->pid);
|
||||
fu_xmlb_builder_insert_kx (bn, "release", priv->release);
|
||||
fu_xmlb_builder_insert_kx (bn, "dfu_version", priv->dfu_version);
|
||||
}
|
||||
|
||||
/* private */
|
||||
@ -387,7 +389,7 @@ static void
|
||||
fu_dfu_firmware_class_init (FuDfuFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->to_string = fu_dfu_firmware_to_string;
|
||||
klass_firmware->export = fu_dfu_firmware_export;
|
||||
klass_firmware->parse = fu_dfu_firmware_parse;
|
||||
klass_firmware->write = fu_dfu_firmware_write;
|
||||
klass_firmware->build = fu_dfu_firmware_build;
|
||||
|
@ -608,6 +608,7 @@ fu_firmware_get_checksum (FuFirmware *self,
|
||||
{
|
||||
FuFirmwarePrivate *priv = GET_PRIVATE (self);
|
||||
FuFirmwareClass *klass = FU_FIRMWARE_GET_CLASS (self);
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
g_return_val_if_fail (FU_IS_FIRMWARE (self), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
@ -617,15 +618,14 @@ fu_firmware_get_checksum (FuFirmware *self,
|
||||
return klass->get_checksum (self, csum_kind, error);
|
||||
|
||||
/* internal data */
|
||||
if (priv->bytes == NULL) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_FOUND,
|
||||
"no bytes found in firmware bytes %s",
|
||||
priv->id);
|
||||
if (priv->bytes != NULL)
|
||||
return g_compute_checksum_for_bytes (csum_kind, priv->bytes);
|
||||
|
||||
/* write */
|
||||
blob = fu_firmware_write (self, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
}
|
||||
return g_compute_checksum_for_bytes (csum_kind, priv->bytes);
|
||||
return g_compute_checksum_for_bytes (csum_kind, blob);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -890,6 +890,84 @@ fu_firmware_build (FuFirmware *self, XbNode *n, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_firmware_build_from_xml:
|
||||
* @self: A #FuFirmware
|
||||
* @xml: XML text
|
||||
* @error: A #GError, or %NULL
|
||||
*
|
||||
* Builds a firmware from an XML manifest. The manifest would typically have the
|
||||
* following form:
|
||||
*
|
||||
* |[<!-- language="XML" -->
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* <firmware gtype="FuBcm57xxFirmware">
|
||||
* <version>1.2.3</version>
|
||||
* <firmware gtype="FuBcm57xxStage1Image">
|
||||
* <version>7.8.9</version>
|
||||
* <id>stage1</id>
|
||||
* <idx>0x01</idx>
|
||||
* <filename>stage1.bin</filename>
|
||||
* </firmware>
|
||||
* <firmware gtype="FuBcm57xxStage2Image">
|
||||
* <id>stage2</id>
|
||||
* <data/> <!-- empty! -->
|
||||
* </firmware>
|
||||
* <firmware gtype="FuBcm57xxDictImage">
|
||||
* <id>ape</id>
|
||||
* <addr>0x7</addr>
|
||||
* <data>aGVsbG8gd29ybGQ=</data> <!-- base64 -->
|
||||
* </firmware>
|
||||
* </firmware>
|
||||
* ]|
|
||||
*
|
||||
* This would be used in a build-system to merge images from generated files:
|
||||
* `fwupdtool firmware-build fw.builder.xml test.fw`
|
||||
*
|
||||
* Static binary content can be specified in the `<firmware>/<data>` section and
|
||||
* is encoded as base64 text if not empty.
|
||||
*
|
||||
* Additionally, extra nodes can be included under nested `<firmware>` objects
|
||||
* which can be parsed by the subclassed objects. You should verify the
|
||||
* subclassed object `FuFirmware->build` vfunc for the specific additional
|
||||
* options supported.
|
||||
*
|
||||
* Plugins should manually g_type_ensure() subclassed image objects if not
|
||||
* constructed as part of the plugin fu_plugin_init() or fu_plugin_setup()
|
||||
* functions.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
*
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
gboolean
|
||||
fu_firmware_build_from_xml (FuFirmware *self, const gchar *xml, GError **error)
|
||||
{
|
||||
g_autoptr(XbBuilder) builder = xb_builder_new ();
|
||||
g_autoptr(XbBuilderSource) source = xb_builder_source_new ();
|
||||
g_autoptr(XbNode) n = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
|
||||
/* parse XML */
|
||||
if (!xb_builder_source_load_xml (source, xml,
|
||||
XB_BUILDER_SOURCE_FLAG_NONE,
|
||||
error)) {
|
||||
g_prefix_error (error, "could not parse XML: ");
|
||||
return FALSE;
|
||||
}
|
||||
xb_builder_import_source (builder, source);
|
||||
silo = xb_builder_compile (builder, XB_BUILDER_COMPILE_FLAG_NONE,
|
||||
NULL, error);
|
||||
if (silo == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* create FuFirmware of specific GType */
|
||||
n = xb_silo_query_first (silo, "firmware", error);
|
||||
if (n == NULL)
|
||||
return FALSE;
|
||||
return fu_firmware_build (self, n, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_firmware_parse_file:
|
||||
* @self: A #FuFirmware
|
||||
@ -1363,14 +1441,30 @@ fu_firmware_get_image_by_idx_bytes (FuFirmware *self, guint64 idx, GError **erro
|
||||
return fu_firmware_write (img, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_firmware_add_string (FuFirmware *self, guint idt, GString *str)
|
||||
/**
|
||||
* fu_firmware_export:
|
||||
* @self: A #FuFirmware
|
||||
* @flags: #FuFirmwareExportFlags, e.g. %FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG
|
||||
* @bn: A #XbBuilderNode
|
||||
*
|
||||
* This allows us to build an XML object for the nested firmware.
|
||||
*
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
void
|
||||
fu_firmware_export (FuFirmware *self,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuFirmwareClass *klass = FU_FIRMWARE_GET_CLASS (self);
|
||||
FuFirmwarePrivate *priv = GET_PRIVATE (self);
|
||||
const gchar *gtypestr = G_OBJECT_TYPE_NAME (self);
|
||||
|
||||
/* object */
|
||||
if (g_strcmp0 (gtypestr, "FuFirmware") != 0)
|
||||
xb_builder_node_set_attr (bn, "gtype", gtypestr);
|
||||
|
||||
/* subclassed type */
|
||||
fu_common_string_append_kv (str, idt, G_OBJECT_TYPE_NAME (self), NULL);
|
||||
if (priv->flags != FU_FIRMWARE_FLAG_NONE) {
|
||||
g_autoptr(GString) tmp = g_string_new ("");
|
||||
for (guint i = 0; i < 64; i++) {
|
||||
@ -1381,51 +1475,84 @@ fu_firmware_add_string (FuFirmware *self, guint idt, GString *str)
|
||||
}
|
||||
if (tmp->len > 0)
|
||||
g_string_truncate (tmp, tmp->len - 1);
|
||||
fu_common_string_append_kv (str, idt, "Flags", tmp->str);
|
||||
fu_xmlb_builder_insert_kv (bn, "flags", tmp->str);
|
||||
}
|
||||
if (priv->id != NULL)
|
||||
fu_common_string_append_kv (str, idt, "ID", priv->id);
|
||||
if (priv->idx != 0x0)
|
||||
fu_common_string_append_kx (str, idt, "Index", priv->idx);
|
||||
if (priv->version != NULL)
|
||||
fu_common_string_append_kv (str, idt, "Version", priv->version);
|
||||
if (priv->version_raw != 0x0)
|
||||
fu_common_string_append_kx (str, idt, "VersionRaw", priv->version_raw);
|
||||
if (priv->addr != 0x0)
|
||||
fu_common_string_append_kx (str, idt, "Address", priv->addr);
|
||||
if (priv->offset != 0x0)
|
||||
fu_common_string_append_kx (str, idt, "Offset", priv->offset);
|
||||
if (priv->size != 0x0)
|
||||
fu_common_string_append_kx (str, idt, "Size", priv->size);
|
||||
if (priv->filename != NULL)
|
||||
fu_common_string_append_kv (str, idt, "Filename", priv->filename);
|
||||
fu_xmlb_builder_insert_kv (bn, "id", priv->id);
|
||||
fu_xmlb_builder_insert_kx (bn, "idx", priv->idx);
|
||||
fu_xmlb_builder_insert_kv (bn, "version", priv->version);
|
||||
fu_xmlb_builder_insert_kx (bn, "version_raw", priv->version_raw);
|
||||
fu_xmlb_builder_insert_kx (bn, "addr", priv->addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "offset", priv->offset);
|
||||
fu_xmlb_builder_insert_kx (bn, "size", priv->size);
|
||||
fu_xmlb_builder_insert_kv (bn, "filename", priv->filename);
|
||||
if (priv->bytes != NULL) {
|
||||
fu_common_string_append_kx (str, idt, "Data",
|
||||
g_bytes_get_size (priv->bytes));
|
||||
}
|
||||
if (priv->alignment != 0x0) {
|
||||
fu_common_string_append_kx (str, idt, "Alignment",
|
||||
(guint64) 1 << priv->alignment);
|
||||
gsize bufsz = 0;
|
||||
const guint8 *buf = g_bytes_get_data (priv->bytes, &bufsz);
|
||||
g_autofree gchar *datastr = NULL;
|
||||
g_autofree gchar *dataszstr = g_strdup_printf ("0x%x", (guint) bufsz);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA) {
|
||||
datastr = fu_common_strsafe ((const gchar *) buf, MIN (bufsz, 16));
|
||||
} else {
|
||||
datastr = g_base64_encode (buf, bufsz);
|
||||
}
|
||||
xb_builder_node_insert_text (bn, "data", datastr,
|
||||
"size", dataszstr,
|
||||
NULL);
|
||||
}
|
||||
fu_xmlb_builder_insert_kx (bn, "alignment", priv->alignment);
|
||||
|
||||
/* add chunks */
|
||||
if (priv->chunks != NULL) {
|
||||
/* chunks */
|
||||
if (priv->chunks != NULL && priv->chunks->len > 0) {
|
||||
g_autoptr(XbBuilderNode) bp = xb_builder_node_insert (bn, "chunks", NULL);
|
||||
for (guint i = 0; i < priv->chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index (priv->chunks, i);
|
||||
fu_chunk_add_string (chk, 1, str);
|
||||
g_autoptr(XbBuilderNode) bc = xb_builder_node_insert (bp, "chunk", NULL);
|
||||
fu_chunk_export (chk, flags, bc);
|
||||
}
|
||||
}
|
||||
|
||||
/* vfunc */
|
||||
if (klass->to_string != NULL)
|
||||
klass->to_string (self, idt, str);
|
||||
if (klass->export != NULL)
|
||||
klass->export (self, flags, bn);
|
||||
|
||||
for (guint i = 0; i < priv->images->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index (priv->images, i);
|
||||
fu_firmware_add_string (img, idt + 1, str);
|
||||
/* children */
|
||||
if (priv->images->len > 0) {
|
||||
for (guint i = 0; i < priv->images->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index (priv->images, i);
|
||||
g_autoptr(XbBuilderNode) bc = xb_builder_node_insert (bn, "firmware", NULL);
|
||||
fu_firmware_export (img, flags, bc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_firmware_export_to_xml:
|
||||
* @self: A #FuFirmware
|
||||
* @flags: #FuFirmwareExportFlags, e.g. %FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG
|
||||
* @error: (nullable): a #GError or %NULL
|
||||
*
|
||||
* This allows us to build an XML object for the nested firmware.
|
||||
*
|
||||
* Returns: a string value, or %NULL for invalid.
|
||||
*
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
gchar *
|
||||
fu_firmware_export_to_xml (FuFirmware *self,
|
||||
FuFirmwareExportFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(XbBuilderNode) bn = xb_builder_node_new ("firmware");
|
||||
fu_firmware_export (self, flags, bn);
|
||||
return xb_builder_node_export (bn,
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_MULTILINE |
|
||||
#if LIBXMLB_CHECK_VERSION(0,2,2)
|
||||
XB_NODE_EXPORT_FLAG_COLLAPSE_EMPTY |
|
||||
#endif
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_INDENT,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_firmware_to_string:
|
||||
* @self: A #FuFirmware
|
||||
@ -1439,9 +1566,15 @@ fu_firmware_add_string (FuFirmware *self, guint idt, GString *str)
|
||||
gchar *
|
||||
fu_firmware_to_string (FuFirmware *self)
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
fu_firmware_add_string (self, 0, str);
|
||||
return g_string_free (str, FALSE);
|
||||
g_autoptr(XbBuilderNode) bn = xb_builder_node_new ("firmware");
|
||||
fu_firmware_export (self, FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG, bn);
|
||||
return xb_builder_node_export (bn,
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_MULTILINE |
|
||||
#if LIBXMLB_CHECK_VERSION(0,2,2)
|
||||
XB_NODE_EXPORT_FLAG_COLLAPSE_EMPTY |
|
||||
#endif
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_INDENT,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -16,6 +16,19 @@
|
||||
#define FU_TYPE_FIRMWARE (fu_firmware_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (FuFirmware, fu_firmware, FU, FIRMWARE, GObject)
|
||||
|
||||
/**
|
||||
* FuFirmwareExportFlags:
|
||||
* @FU_FIRMWARE_EXPORT_FLAG_NONE: No flags set
|
||||
* @FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG: Include debug information when exporting
|
||||
* @FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA: Write the data as UTF-8 strings
|
||||
*
|
||||
* The firmware export flags.
|
||||
**/
|
||||
#define FU_FIRMWARE_EXPORT_FLAG_NONE (0u) /* Since: 1.6.0 */
|
||||
#define FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG (1u << 0) /* Since: 1.6.0 */
|
||||
#define FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA (1u << 1) /* Since: 1.6.0 */
|
||||
typedef guint64 FuFirmwareExportFlags;
|
||||
|
||||
struct _FuFirmwareClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
@ -29,9 +42,9 @@ struct _FuFirmwareClass
|
||||
GBytes *(*write) (FuFirmware *self,
|
||||
GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
void (*to_string) (FuFirmware *self,
|
||||
guint indent,
|
||||
GString *str);
|
||||
void (*export) (FuFirmware *self,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn);
|
||||
gboolean (*tokenize) (FuFirmware *self,
|
||||
GBytes *fw,
|
||||
FwupdInstallFlags flags,
|
||||
@ -66,9 +79,9 @@ struct _FuFirmwareClass
|
||||
#define FU_FIRMWARE_FLAG_HAS_VID_PID (1u << 3) /* Since: 1.5.6 */
|
||||
typedef guint64 FuFirmwareFlags;
|
||||
|
||||
#define FU_FIRMWARE_ID_PAYLOAD "payload"
|
||||
#define FU_FIRMWARE_ID_PAYLOAD "payload"
|
||||
#define FU_FIRMWARE_ID_SIGNATURE "signature"
|
||||
#define FU_FIRMWARE_ID_HEADER "header"
|
||||
#define FU_FIRMWARE_ID_HEADER "header"
|
||||
|
||||
const gchar *fu_firmware_flag_to_string (FuFirmwareFlags flag);
|
||||
FuFirmwareFlags fu_firmware_flag_from_string (const gchar *flag);
|
||||
@ -80,6 +93,12 @@ FuFirmware *fu_firmware_new_from_gtypes (GBytes *fw,
|
||||
GError **error,
|
||||
...);
|
||||
gchar *fu_firmware_to_string (FuFirmware *self);
|
||||
void fu_firmware_export (FuFirmware *self,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn);
|
||||
gchar *fu_firmware_export_to_xml (FuFirmware *self,
|
||||
FuFirmwareExportFlags flags,
|
||||
GError **error);
|
||||
const gchar *fu_firmware_get_version (FuFirmware *self);
|
||||
void fu_firmware_set_version (FuFirmware *self,
|
||||
const gchar *version);
|
||||
@ -129,6 +148,10 @@ gboolean fu_firmware_build (FuFirmware *self,
|
||||
XbNode *n,
|
||||
GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean fu_firmware_build_from_xml (FuFirmware *self,
|
||||
const gchar *xml,
|
||||
GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean fu_firmware_parse (FuFirmware *self,
|
||||
GBytes *fw,
|
||||
FwupdInstallFlags flags,
|
||||
|
@ -54,13 +54,14 @@ fu_fmap_firmware_find_offset (FuFmapFirmware *self,
|
||||
}
|
||||
|
||||
static void
|
||||
fu_fmap_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_fmap_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuFmapFirmware *self = FU_FMAP_FIRMWARE (firmware);
|
||||
FuFmapFirmwarePrivate *priv = GET_PRIVATE (self);
|
||||
if (priv->offset > 0)
|
||||
fu_common_string_append_kx (str, idt, "Offset", priv->offset);
|
||||
fu_common_string_append_kx (str, idt, "Base", priv->base);
|
||||
fu_xmlb_builder_insert_kx (bn, "offset", priv->offset);
|
||||
fu_xmlb_builder_insert_kx (bn, "base", priv->base);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -260,7 +261,7 @@ static void
|
||||
fu_fmap_firmware_class_init (FuFmapFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->to_string = fu_fmap_firmware_to_string;
|
||||
klass_firmware->export = fu_fmap_firmware_export;
|
||||
klass_firmware->parse = fu_fmap_firmware_parse;
|
||||
klass_firmware->write = fu_fmap_firmware_write;
|
||||
klass_firmware->build = fu_fmap_firmware_build;
|
||||
|
@ -1320,117 +1320,98 @@ fu_chunk_func (void)
|
||||
|
||||
chunked3 = fu_chunk_array_new ((const guint8 *) "123456", 6, 0x0, 3, 3);
|
||||
chunked3_str = fu_chunk_array_to_string (chunked3);
|
||||
g_assert_cmpstr (chunked3_str, ==, "FuChunk:\n"
|
||||
" Index: 0x0\n"
|
||||
" Page: 0x0\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: 123\n"
|
||||
" DataSz: 0x3\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x1\n"
|
||||
" Page: 0x1\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: 456\n"
|
||||
" DataSz: 0x3\n");
|
||||
g_assert_cmpstr (chunked3_str, ==,
|
||||
"<chunks>\n"
|
||||
" <chunk>\n"
|
||||
" <data size=\"0x3\">123</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x1</idx>\n"
|
||||
" <page>0x1</page>\n"
|
||||
" <data size=\"0x3\">456</data>\n"
|
||||
" </chunk>\n"
|
||||
"</chunks>\n");
|
||||
|
||||
chunked4 = fu_chunk_array_new ((const guint8 *) "123456", 6, 0x4, 4, 4);
|
||||
chunked4_str = fu_chunk_array_to_string (chunked4);
|
||||
g_assert_cmpstr (chunked4_str, ==, "FuChunk:\n"
|
||||
" Index: 0x0\n"
|
||||
" Page: 0x1\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: 1234\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x1\n"
|
||||
" Page: 0x2\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: 56\n"
|
||||
" DataSz: 0x2\n");
|
||||
g_assert_cmpstr (chunked4_str, ==,
|
||||
"<chunks>\n"
|
||||
" <chunk>\n"
|
||||
" <page>0x1</page>\n"
|
||||
" <data size=\"0x4\">1234</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x1</idx>\n"
|
||||
" <page>0x2</page>\n"
|
||||
" <data size=\"0x2\">56</data>\n"
|
||||
" </chunk>\n"
|
||||
"</chunks>\n");
|
||||
|
||||
chunked1 = fu_chunk_array_new ((const guint8 *) "0123456789abcdef", 16, 0x0, 10, 4);
|
||||
chunked1_str = fu_chunk_array_to_string (chunked1);
|
||||
g_assert_cmpstr (chunked1_str, ==, "FuChunk:\n"
|
||||
" Index: 0x0\n"
|
||||
" Page: 0x0\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: 0123\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x1\n"
|
||||
" Page: 0x0\n"
|
||||
" Address: 0x4\n"
|
||||
" Data: 4567\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x2\n"
|
||||
" Page: 0x0\n"
|
||||
" Address: 0x8\n"
|
||||
" Data: 89\n"
|
||||
" DataSz: 0x2\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x3\n"
|
||||
" Page: 0x1\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: abcd\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x4\n"
|
||||
" Page: 0x1\n"
|
||||
" Address: 0x4\n"
|
||||
" Data: ef\n"
|
||||
" DataSz: 0x2\n");
|
||||
|
||||
g_assert_cmpstr (chunked1_str, ==,
|
||||
"<chunks>\n"
|
||||
" <chunk>\n"
|
||||
" <data size=\"0x4\">0123</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x1</idx>\n"
|
||||
" <addr>0x4</addr>\n"
|
||||
" <data size=\"0x4\">4567</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x2</idx>\n"
|
||||
" <addr>0x8</addr>\n"
|
||||
" <data size=\"0x2\">89</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x3</idx>\n"
|
||||
" <page>0x1</page>\n"
|
||||
" <data size=\"0x4\">abcd</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x4</idx>\n"
|
||||
" <page>0x1</page>\n"
|
||||
" <addr>0x4</addr>\n"
|
||||
" <data size=\"0x2\">ef</data>\n"
|
||||
" </chunk>\n"
|
||||
"</chunks>\n");
|
||||
chunked2 = fu_chunk_array_new ((const guint8 *) "XXXXXXYYYYYYZZZZZZ", 18, 0x0, 6, 4);
|
||||
chunked2_str = fu_chunk_array_to_string (chunked2);
|
||||
g_print ("\n%s", chunked2_str);
|
||||
g_assert_cmpstr (chunked2_str, ==, "FuChunk:\n"
|
||||
" Index: 0x0\n"
|
||||
" Page: 0x0\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: XXXX\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x1\n"
|
||||
" Page: 0x0\n"
|
||||
" Address: 0x4\n"
|
||||
" Data: XX\n"
|
||||
" DataSz: 0x2\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x2\n"
|
||||
" Page: 0x1\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: YYYY\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x3\n"
|
||||
" Page: 0x1\n"
|
||||
" Address: 0x4\n"
|
||||
" Data: YY\n"
|
||||
" DataSz: 0x2\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x4\n"
|
||||
" Page: 0x2\n"
|
||||
" Address: 0x0\n"
|
||||
" Data: ZZZZ\n"
|
||||
" DataSz: 0x4\n"
|
||||
"\n"
|
||||
"FuChunk:\n"
|
||||
" Index: 0x5\n"
|
||||
" Page: 0x2\n"
|
||||
" Address: 0x4\n"
|
||||
" Data: ZZ\n"
|
||||
" DataSz: 0x2\n");
|
||||
g_assert_cmpstr (chunked2_str, ==,
|
||||
"<chunks>\n"
|
||||
" <chunk>\n"
|
||||
" <data size=\"0x4\">XXXX</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x1</idx>\n"
|
||||
" <addr>0x4</addr>\n"
|
||||
" <data size=\"0x2\">XX</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x2</idx>\n"
|
||||
" <page>0x1</page>\n"
|
||||
" <data size=\"0x4\">YYYY</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x3</idx>\n"
|
||||
" <page>0x1</page>\n"
|
||||
" <addr>0x4</addr>\n"
|
||||
" <data size=\"0x2\">YY</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x4</idx>\n"
|
||||
" <page>0x2</page>\n"
|
||||
" <data size=\"0x4\">ZZZZ</data>\n"
|
||||
" </chunk>\n"
|
||||
" <chunk>\n"
|
||||
" <idx>0x5</idx>\n"
|
||||
" <page>0x2</page>\n"
|
||||
" <addr>0x4</addr>\n"
|
||||
" <data size=\"0x2\">ZZ</data>\n"
|
||||
" </chunk>\n"
|
||||
"</chunks>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2134,16 +2115,20 @@ fu_firmware_func (void)
|
||||
g_assert_cmpstr (fu_firmware_get_id (img_idx), ==, "secondary");
|
||||
|
||||
str = fu_firmware_to_string (firmware);
|
||||
g_assert_cmpstr (str, ==, "FuFirmware:\n"
|
||||
" FuFirmware:\n"
|
||||
" ID: primary\n"
|
||||
" Index: 0xd\n"
|
||||
" Address: 0x200\n"
|
||||
" Filename: BIOS.bin\n"
|
||||
" FuFirmware:\n"
|
||||
" ID: secondary\n"
|
||||
" Index: 0x17\n"
|
||||
" Address: 0x400\n");
|
||||
g_assert_cmpstr (str, ==,
|
||||
"<firmware>\n"
|
||||
" <firmware>\n"
|
||||
" <id>primary</id>\n"
|
||||
" <idx>0xd</idx>\n"
|
||||
" <addr>0x200</addr>\n"
|
||||
" <filename>BIOS.bin</filename>\n"
|
||||
" </firmware>\n"
|
||||
" <firmware>\n"
|
||||
" <id>secondary</id>\n"
|
||||
" <idx>0x17</idx>\n"
|
||||
" <addr>0x400</addr>\n"
|
||||
" </firmware>\n"
|
||||
"</firmware>\n");
|
||||
|
||||
ret = fu_firmware_remove_image_by_idx (firmware, 0xd, &error);
|
||||
g_assert_no_error (error);
|
||||
@ -2464,6 +2449,147 @@ fu_security_attrs_hsi_func (void)
|
||||
g_assert_cmpstr (hsi8, ==, expected_hsi8);
|
||||
g_clear_object (&attr);
|
||||
}
|
||||
static void
|
||||
fu_firmware_dfuse_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_dfuse_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_dfuse_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/dfuse.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "c1ff429f0e381c8fe8e1b2ee41a5a9a79e2f2ff7");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
static void
|
||||
fu_firmware_srec_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_srec_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_srec_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/srec.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
static void
|
||||
fu_firmware_ihex_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_ihex_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_ihex_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/ihex.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "a8d74f767f3fc992b413e5ba801cedc80a4cf013");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
static void
|
||||
fu_firmware_fmap_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_fmap_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_fmap_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/fmap.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "a0b9ffc10a586d217edf9e9bae7c1fe7c564ea01");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
@ -2520,13 +2646,17 @@ main (int argc, char **argv)
|
||||
g_test_add_func ("/fwupd/firmware{dedupe}", fu_firmware_dedupe_func);
|
||||
g_test_add_func ("/fwupd/firmware{build}", fu_firmware_build_func);
|
||||
g_test_add_func ("/fwupd/firmware{ihex}", fu_firmware_ihex_func);
|
||||
g_test_add_func ("/fwupd/firmware{ihex-xml}", fu_firmware_ihex_xml_func);
|
||||
g_test_add_func ("/fwupd/firmware{ihex-offset}", fu_firmware_ihex_offset_func);
|
||||
g_test_add_func ("/fwupd/firmware{ihex-signed}", fu_firmware_ihex_signed_func);
|
||||
g_test_add_func ("/fwupd/firmware{srec-tokenization}", fu_firmware_srec_tokenization_func);
|
||||
g_test_add_func ("/fwupd/firmware{srec}", fu_firmware_srec_func);
|
||||
g_test_add_func ("/fwupd/firmware{srec-xml}", fu_firmware_srec_xml_func);
|
||||
g_test_add_func ("/fwupd/firmware{dfu}", fu_firmware_dfu_func);
|
||||
g_test_add_func ("/fwupd/firmware{dfuse}", fu_firmware_dfuse_func);
|
||||
g_test_add_func ("/fwupd/firmware{dfuse-xml}", fu_firmware_dfuse_xml_func);
|
||||
g_test_add_func ("/fwupd/firmware{fmap}", fu_firmware_fmap_func);
|
||||
g_test_add_func ("/fwupd/firmware{fmap-xml}", fu_firmware_fmap_xml_func);
|
||||
g_test_add_func ("/fwupd/firmware{gtypes}", fu_firmware_new_from_gtypes_func);
|
||||
g_test_add_func ("/fwupd/archive{invalid}", fu_archive_invalid_func);
|
||||
g_test_add_func ("/fwupd/archive{cab}", fu_archive_cab_func);
|
||||
|
@ -479,19 +479,24 @@ fu_smbios_setup (FuSmbios *self, GError **error)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_smbios_to_string_internal (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_smbios_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuSmbios *self = FU_SMBIOS (firmware);
|
||||
|
||||
for (guint i = 0; i < self->items->len; i++) {
|
||||
FuSmbiosItem *item = g_ptr_array_index (self->items, i);
|
||||
fu_common_string_append_kx (str, idt + 0, "Type", item->type);
|
||||
fu_common_string_append_kx (str, idt + 1, "Length", item->buf->len);
|
||||
fu_common_string_append_kx (str, idt + 1, "Handle", item->handle);
|
||||
g_autoptr(XbBuilderNode) bc = xb_builder_node_insert (bn, "item", NULL);
|
||||
fu_xmlb_builder_insert_kx (bc, "type", item->type);
|
||||
fu_xmlb_builder_insert_kx (bc, "length", item->buf->len);
|
||||
fu_xmlb_builder_insert_kx (bc, "handle", item->handle);
|
||||
for (guint j = 0; j < item->strings->len; j++) {
|
||||
const gchar *tmp = g_ptr_array_index (item->strings, j);
|
||||
g_autofree gchar *title = g_strdup_printf ("String[%02u]", j);
|
||||
g_autofree gchar *title = g_strdup_printf ("%02u", j);
|
||||
g_autofree gchar *value = fu_common_strsafe (tmp, 20);
|
||||
fu_common_string_append_kv (str, idt + 2, title, value);
|
||||
xb_builder_node_insert_text (bc, "string", value,
|
||||
"idx", title, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -689,7 +694,7 @@ fu_smbios_class_init (FuSmbiosClass *klass)
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
object_class->finalize = fu_smbios_finalize;
|
||||
klass_firmware->parse = fu_smbios_parse;
|
||||
klass_firmware->to_string = fu_smbios_to_string_internal;
|
||||
klass_firmware->export = fu_smbios_export;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -761,6 +761,9 @@ LIBFWUPDPLUGIN_1.6.0 {
|
||||
fu_byte_array_set_size_full;
|
||||
fu_common_align_up;
|
||||
fu_firmware_add_chunk;
|
||||
fu_firmware_build_from_xml;
|
||||
fu_firmware_export;
|
||||
fu_firmware_export_to_xml;
|
||||
fu_firmware_get_addr;
|
||||
fu_firmware_get_alignment;
|
||||
fu_firmware_get_bytes;
|
||||
@ -780,5 +783,8 @@ LIBFWUPDPLUGIN_1.6.0 {
|
||||
fu_firmware_set_offset;
|
||||
fu_firmware_set_size;
|
||||
fu_firmware_write_chunk;
|
||||
fu_xmlb_builder_insert_kb;
|
||||
fu_xmlb_builder_insert_kv;
|
||||
fu_xmlb_builder_insert_kx;
|
||||
local: *;
|
||||
} LIBFWUPDPLUGIN_1.5.8;
|
||||
|
@ -471,6 +471,7 @@ conf.set_quoted('FWUPD_DATADIR', datadir)
|
||||
conf.set_quoted('FWUPD_LOCALSTATEDIR', localstatedir)
|
||||
conf.set_quoted('FWUPD_SYSCONFDIR', sysconfdir)
|
||||
conf.set_quoted('FWUPD_LOCALEDIR', localedir)
|
||||
conf.set_quoted('FWUPD_FUZZINGSRCDIR', join_paths(meson.source_root(), 'src', 'fuzzing'))
|
||||
|
||||
if build_standalone
|
||||
if host_machine.system() == 'windows'
|
||||
|
@ -20,17 +20,19 @@ struct _FuBcm57xxDictImage {
|
||||
G_DEFINE_TYPE (FuBcm57xxDictImage, fu_bcm57xx_dict_image, FU_TYPE_FIRMWARE)
|
||||
|
||||
static void
|
||||
fu_bcm57xx_dict_image_to_string (FuFirmware *image, guint idt, GString *str)
|
||||
fu_bcm57xx_dict_image_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuBcm57xxDictImage *self = FU_BCM57XX_DICT_IMAGE (image);
|
||||
FuBcm57xxDictImage *self = FU_BCM57XX_DICT_IMAGE (firmware);
|
||||
if (self->target != 0xff)
|
||||
fu_common_string_append_kx (str, idt, "Target", self->target);
|
||||
fu_xmlb_builder_insert_kx (bn, "target", self->target);
|
||||
if (self->kind != 0xff)
|
||||
fu_common_string_append_kx (str, idt, "Kind", self->kind);
|
||||
fu_xmlb_builder_insert_kx (bn, "kind", self->kind);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_bcm57xx_dict_image_parse (FuFirmware *image,
|
||||
fu_bcm57xx_dict_image_parse (FuFirmware *firmware,
|
||||
GBytes *fw,
|
||||
guint64 addr_start,
|
||||
guint64 addr_end,
|
||||
@ -47,12 +49,12 @@ fu_bcm57xx_dict_image_parse (FuFirmware *image,
|
||||
error);
|
||||
if (fw_nocrc == NULL)
|
||||
return FALSE;
|
||||
fu_firmware_set_bytes (image, fw_nocrc);
|
||||
fu_firmware_set_bytes (firmware, fw_nocrc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_bcm57xx_dict_image_write (FuFirmware *image, GError **error)
|
||||
fu_bcm57xx_dict_image_write (FuFirmware *firmware, GError **error)
|
||||
{
|
||||
const guint8 *buf;
|
||||
gsize bufsz = 0;
|
||||
@ -61,7 +63,7 @@ fu_bcm57xx_dict_image_write (FuFirmware *image, GError **error)
|
||||
g_autoptr(GBytes) fw_nocrc = NULL;
|
||||
|
||||
/* get the CRC-less data */
|
||||
fw_nocrc = fu_firmware_get_bytes (image, error);
|
||||
fw_nocrc = fu_firmware_get_bytes (firmware, error);
|
||||
if (fw_nocrc == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -77,9 +79,9 @@ fu_bcm57xx_dict_image_write (FuFirmware *image, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_bcm57xx_dict_image_build (FuFirmware *image, XbNode *n, GError **error)
|
||||
fu_bcm57xx_dict_image_build (FuFirmware *firmware, XbNode *n, GError **error)
|
||||
{
|
||||
FuBcm57xxDictImage *self = FU_BCM57XX_DICT_IMAGE (image);
|
||||
FuBcm57xxDictImage *self = FU_BCM57XX_DICT_IMAGE (firmware);
|
||||
guint64 tmp;
|
||||
|
||||
/* two simple properties */
|
||||
@ -167,7 +169,7 @@ fu_bcm57xx_dict_image_class_init (FuBcm57xxDictImageClass *klass)
|
||||
klass_image->parse = fu_bcm57xx_dict_image_parse;
|
||||
klass_image->write = fu_bcm57xx_dict_image_write;
|
||||
klass_image->build = fu_bcm57xx_dict_image_build;
|
||||
klass_image->to_string = fu_bcm57xx_dict_image_to_string;
|
||||
klass_image->export = fu_bcm57xx_dict_image_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -35,13 +35,17 @@ G_DEFINE_TYPE (FuBcm57xxFirmware, fu_bcm57xx_firmware, FU_TYPE_FIRMWARE)
|
||||
#define BCM_CODE_DIRECTORY_ADDR_APE 0x07
|
||||
|
||||
static void
|
||||
fu_bcm57xx_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_bcm57xx_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuBcm57xxFirmware *self = FU_BCM57XX_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "Vendor", self->vendor);
|
||||
fu_common_string_append_kx (str, idt, "Model", self->model);
|
||||
fu_common_string_append_kb (str, idt, "IsBackup", self->is_backup);
|
||||
fu_common_string_append_kx (str, idt, "PhysAddr", self->phys_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "vendor", self->vendor);
|
||||
fu_xmlb_builder_insert_kx (bn, "model", self->model);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kb (bn, "is_backup", self->is_backup);
|
||||
fu_xmlb_builder_insert_kx (bn, "phys_addr", self->phys_addr);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -589,7 +593,7 @@ fu_bcm57xx_firmware_class_init (FuBcm57xxFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_bcm57xx_firmware_parse;
|
||||
klass_firmware->to_string = fu_bcm57xx_firmware_to_string;
|
||||
klass_firmware->export = fu_bcm57xx_firmware_export;
|
||||
klass_firmware->write = fu_bcm57xx_firmware_write;
|
||||
klass_firmware->build = fu_bcm57xx_firmware_build;
|
||||
}
|
||||
|
@ -11,7 +11,10 @@
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-bcm57xx-common.h"
|
||||
#include "fu-bcm57xx-dict-image.h"
|
||||
#include "fu-bcm57xx-firmware.h"
|
||||
#include "fu-bcm57xx-stage1-image.h"
|
||||
#include "fu-bcm57xx-stage2-image.h"
|
||||
|
||||
static void
|
||||
fu_bcm57xx_create_verbuf (guint8 *bufver, const gchar *version)
|
||||
@ -88,15 +91,55 @@ fu_bcm57xx_firmware_talos_func (void)
|
||||
g_assert_true (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_bcm57xx_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_bcm57xx_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_bcm57xx_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/bcm57xx.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "a3ac108905c37857cf48612b707c1c72c582f914");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_type_ensure (FU_TYPE_BCM57XX_STAGE1_IMAGE);
|
||||
g_type_ensure (FU_TYPE_BCM57XX_STAGE2_IMAGE);
|
||||
g_type_ensure (FU_TYPE_BCM57XX_DICT_IMAGE);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/fwupd/bcm57xx/firmware{xml}", fu_bcm57xx_firmware_xml_func);
|
||||
g_test_add_func ("/fwupd/bcm57xx/firmware{talos}", fu_bcm57xx_firmware_talos_func);
|
||||
g_test_add_func ("/fwupd/bcm57xx/common{veritem}", fu_bcm57xx_common_veritem_func);
|
||||
return g_test_run ();
|
||||
|
@ -75,11 +75,15 @@ fu_ccgx_dmc_firmware_get_fw_data_size (FuCcgxDmcFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_dmc_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_ccgx_dmc_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuCcgxDmcFirmware *self = FU_CCGX_DMC_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "FwDataSize", self->fw_data_size);
|
||||
fu_common_string_append_ku (str, idt, "ImageRecords", self->image_records->len);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kx (bn, "fw_data_size", self->fw_data_size);
|
||||
fu_xmlb_builder_insert_kx (bn, "image_records", self->image_records->len);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -466,7 +470,7 @@ fu_ccgx_dmc_firmware_class_init (FuCcgxDmcFirmwareClass *klass)
|
||||
object_class->finalize = fu_ccgx_dmc_firmware_finalize;
|
||||
klass_firmware->parse = fu_ccgx_dmc_firmware_parse;
|
||||
klass_firmware->write = fu_ccgx_dmc_firmware_write;
|
||||
klass_firmware->to_string = fu_ccgx_dmc_firmware_to_string;
|
||||
klass_firmware->export = fu_ccgx_dmc_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -58,14 +58,18 @@ fu_ccgx_firmware_get_fw_mode (FuCcgxFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_ccgx_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuCcgxFirmware *self = FU_CCGX_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "AppType", self->app_type);
|
||||
fu_common_string_append_kx (str, idt, "SiliconId", self->silicon_id);
|
||||
fu_common_string_append_ku (str, idt, "Records", self->records->len);
|
||||
fu_common_string_append_kv (str, idt, "FWMode",
|
||||
fu_ccgx_fw_mode_to_string (self->fw_mode));
|
||||
fu_xmlb_builder_insert_kx (bn, "silicon_id", self->silicon_id);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kx (bn, "app_type", self->app_type);
|
||||
fu_xmlb_builder_insert_kx (bn, "records", self->records->len);
|
||||
fu_xmlb_builder_insert_kv (bn, "fw_mode",
|
||||
fu_ccgx_fw_mode_to_string (self->fw_mode));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -467,7 +471,7 @@ fu_ccgx_firmware_class_init (FuCcgxFirmwareClass *klass)
|
||||
klass_firmware->parse = fu_ccgx_firmware_parse;
|
||||
klass_firmware->write = fu_ccgx_firmware_write;
|
||||
klass_firmware->build = fu_ccgx_firmware_build;
|
||||
klass_firmware->to_string = fu_ccgx_firmware_to_string;
|
||||
klass_firmware->export = fu_ccgx_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
97
plugins/ccgx/fu-self-test.c
Normal file
97
plugins/ccgx/fu-self-test.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-ccgx-firmware.h"
|
||||
#include "fu-ccgx-dmc-firmware.h"
|
||||
|
||||
static void
|
||||
fu_ccgx_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_ccgx_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_ccgx_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/ccgx.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_dmc_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_ccgx_dmc_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_ccgx_dmc_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/ccgx-dmc.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/ccgx/firmware{xml}", fu_ccgx_firmware_xml_func);
|
||||
g_test_add_func ("/ccgx-dmc/firmware{xml}", fu_ccgx_dmc_firmware_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
@ -39,3 +39,32 @@ shared_module('fu_plugin_ccgx',
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tests')
|
||||
e = executable(
|
||||
'ccgx-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-ccgx-common.c',
|
||||
'fu-ccgx-firmware.c',
|
||||
'fu-ccgx-dmc-common.c',
|
||||
'fu-ccgx-dmc-firmware.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
install : true,
|
||||
install_dir : installed_test_bindir,
|
||||
)
|
||||
test('ccgx-self-test', e)
|
||||
endif
|
||||
|
@ -39,11 +39,13 @@ fu_elantp_firmware_get_iap_addr (FuElantpFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_elantp_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_elantp_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuElantpFirmware *self = FU_ELANTP_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "IapAddr", self->iap_addr);
|
||||
fu_common_string_append_kx (str, idt, "ModuleId", self->module_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "iap_addr", self->iap_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "module_id", self->module_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -185,7 +187,7 @@ fu_elantp_firmware_class_init (FuElantpFirmwareClass *klass)
|
||||
klass_firmware->parse = fu_elantp_firmware_parse;
|
||||
klass_firmware->build = fu_elantp_firmware_build;
|
||||
klass_firmware->write = fu_elantp_firmware_write;
|
||||
klass_firmware->to_string = fu_elantp_firmware_to_string;
|
||||
klass_firmware->export = fu_elantp_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
59
plugins/elantp/fu-self-test.c
Normal file
59
plugins/elantp/fu-self-test.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-elantp-firmware.h"
|
||||
|
||||
static void
|
||||
fu_elantp_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_elantp_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_elantp_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/elantp.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/elantp/firmware{xml}", fu_elantp_firmware_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
@ -36,3 +36,29 @@ shared_module('fu_plugin_elantp',
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tests')
|
||||
e = executable(
|
||||
'elantp-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-elantp-firmware.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
install : true,
|
||||
install_dir : installed_test_bindir,
|
||||
)
|
||||
test('elantp-self-test', e)
|
||||
endif
|
||||
|
@ -24,10 +24,12 @@ fu_fresco_pd_firmware_get_customer_id (FuFrescoPdFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_fresco_pd_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_fresco_pd_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuFrescoPdFirmware *self = FU_FRESCO_PD_FIRMWARE (firmware);
|
||||
fu_common_string_append_ku (str, idt, "CustomerID", self->customer_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "customer_id", self->customer_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -70,7 +72,7 @@ fu_fresco_pd_firmware_class_init (FuFrescoPdFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_fresco_pd_firmware_parse;
|
||||
klass_firmware->to_string = fu_fresco_pd_firmware_to_string;
|
||||
klass_firmware->export = fu_fresco_pd_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -28,10 +28,12 @@ fu_pxi_firmware_get_model_name (FuPxiFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_pxi_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_pxi_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuPxiFirmware *self = FU_PXI_FIRMWARE (firmware);
|
||||
fu_common_string_append_kv (str, idt, "ModelName", self->model_name);
|
||||
fu_xmlb_builder_insert_kv (bn, "model_name", self->model_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -206,7 +208,7 @@ fu_pxi_firmware_class_init (FuPxiFirmwareClass *klass)
|
||||
klass_firmware->parse = fu_pxi_firmware_parse;
|
||||
klass_firmware->build = fu_pxi_firmware_build;
|
||||
klass_firmware->write = fu_pxi_firmware_write;
|
||||
klass_firmware->to_string = fu_pxi_firmware_to_string;
|
||||
klass_firmware->export = fu_pxi_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
59
plugins/pixart-rf/fu-self-test.c
Normal file
59
plugins/pixart-rf/fu-self-test.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-pxi-firmware.h"
|
||||
|
||||
static void
|
||||
fu_pxi_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_pxi_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_pxi_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/pixart.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/pxi/firmware{xml}", fu_pxi_firmware_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
@ -29,3 +29,29 @@ shared_module('fu_plugin_pixart_rf',
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tests')
|
||||
e = executable(
|
||||
'pxi-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-pxi-firmware.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
install : true,
|
||||
install_dir : installed_test_bindir,
|
||||
)
|
||||
test('pxi-self-test', e)
|
||||
endif
|
||||
|
@ -96,22 +96,20 @@ fu_efi_firmware_file_type_to_string (guint8 type)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_efi_firmware_file_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_efi_firmware_file_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuEfiFirmwareFile *self = FU_EFI_FIRMWARE_FILE (firmware);
|
||||
FuEfiFirmwareFilePrivate *priv = GET_PRIVATE (self);
|
||||
const gchar *type_name = fu_efi_firmware_file_type_to_string (priv->type);
|
||||
const gchar *guid_name = fu_efi_guid_to_name (fu_firmware_get_id (firmware));
|
||||
|
||||
if (guid_name != NULL)
|
||||
fu_common_string_append_kv (str, idt, "Name", guid_name);
|
||||
if (priv->attrib != 0x0)
|
||||
fu_common_string_append_kx (str, idt, "Attrib", priv->attrib);
|
||||
if (type_name != NULL) {
|
||||
g_autofree gchar *tmp = g_strdup_printf ("%s [0x%02x]", type_name, priv->type);
|
||||
fu_common_string_append_kv (str, idt, "Type", tmp);
|
||||
} else {
|
||||
fu_common_string_append_kx (str, idt, "Type", priv->type);
|
||||
fu_xmlb_builder_insert_kx (bn, "attrib", priv->attrib);
|
||||
fu_xmlb_builder_insert_kx (bn, "type", priv->type);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kv (bn, "name",
|
||||
fu_efi_guid_to_name (fu_firmware_get_id (firmware)));
|
||||
fu_xmlb_builder_insert_kv (bn, "type_name",
|
||||
fu_efi_firmware_file_type_to_string (priv->type));
|
||||
}
|
||||
}
|
||||
|
||||
@ -367,7 +365,7 @@ fu_efi_firmware_file_class_init (FuEfiFirmwareFileClass *klass)
|
||||
klass_firmware->parse = fu_efi_firmware_file_parse;
|
||||
klass_firmware->write = fu_efi_firmware_file_write;
|
||||
klass_firmware->build = fu_efi_firmware_file_build;
|
||||
klass_firmware->to_string = fu_efi_firmware_file_to_string;
|
||||
klass_firmware->export = fu_efi_firmware_file_export;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,21 +82,20 @@ fu_efi_firmware_section_type_to_string (guint8 type)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_efi_firmware_section_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_efi_firmware_section_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuEfiFirmwareSection *self = FU_EFI_FIRMWARE_SECTION (firmware);
|
||||
FuEfiFirmwareSectionPrivate *priv = GET_PRIVATE (self);
|
||||
const gchar *type_name = fu_efi_firmware_section_type_to_string (priv->type);
|
||||
const gchar *guid_name = fu_efi_guid_to_name (fu_firmware_get_id (firmware));
|
||||
|
||||
if (type_name != NULL) {
|
||||
g_autofree gchar *tmp = g_strdup_printf ("%s [0x%02x]", type_name, priv->type);
|
||||
fu_common_string_append_kv (str, idt, "Type", tmp);
|
||||
} else {
|
||||
fu_common_string_append_kx (str, idt, "Type", priv->type);
|
||||
fu_xmlb_builder_insert_kx (bn, "type", priv->type);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kv (bn, "name",
|
||||
fu_efi_guid_to_name (fu_firmware_get_id (firmware)));
|
||||
fu_xmlb_builder_insert_kv (bn, "type_name",
|
||||
fu_efi_firmware_section_type_to_string (priv->type));
|
||||
}
|
||||
if (guid_name != NULL)
|
||||
fu_common_string_append_kv (str, idt, "Name", guid_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -263,7 +262,7 @@ fu_efi_firmware_section_class_init (FuEfiFirmwareSectionClass *klass)
|
||||
klass_firmware->parse = fu_efi_firmware_section_parse;
|
||||
klass_firmware->write = fu_efi_firmware_section_write;
|
||||
klass_firmware->build = fu_efi_firmware_section_build;
|
||||
klass_firmware->to_string = fu_efi_firmware_section_to_string;
|
||||
klass_firmware->export = fu_efi_firmware_section_export;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,14 +44,17 @@ G_DEFINE_TYPE_WITH_PRIVATE (FuEfiFirmwareVolume, fu_efi_firmware_volume, FU_TYPE
|
||||
#define FU_EFI_FIRMWARE_VOLUME_SIZE 0x40
|
||||
|
||||
static void
|
||||
fu_ifd_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_ifd_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuEfiFirmwareVolume *self = FU_EFI_FIRMWARE_VOLUME (firmware);
|
||||
FuEfiFirmwareVolumePrivate *priv = GET_PRIVATE (self);
|
||||
const gchar *guid_name = fu_efi_guid_to_name (fu_firmware_get_id (firmware));
|
||||
if (guid_name != NULL)
|
||||
fu_common_string_append_kv (str, idt, "Name", guid_name);
|
||||
fu_common_string_append_kx (str, idt, "Attrs", priv->attrs);
|
||||
fu_xmlb_builder_insert_kx (bn, "attrs", priv->attrs);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kv (bn, "name",
|
||||
fu_efi_guid_to_name (fu_firmware_get_id (firmware)));
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -356,7 +359,7 @@ fu_efi_firmware_volume_class_init (FuEfiFirmwareVolumeClass *klass)
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_efi_firmware_volume_parse;
|
||||
klass_firmware->write = fu_efi_firmware_volume_write;
|
||||
klass_firmware->to_string = fu_ifd_firmware_to_string;
|
||||
klass_firmware->export = fu_ifd_firmware_export;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,30 +80,6 @@ fu_ifd_bios_parse (FuFirmware *firmware,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_ifd_bios_write (FuFirmware *firmware, GError **error)
|
||||
{
|
||||
g_autoptr(GByteArray) buf = g_byte_array_new ();
|
||||
g_autoptr(GPtrArray) images = fu_firmware_get_images (firmware);
|
||||
|
||||
/* add each volume */
|
||||
for (guint i = 0; i < images->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index (images, i);
|
||||
g_autoptr(GBytes) bytes = fu_firmware_write (img, error);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
fu_byte_array_append_bytes (buf, bytes);
|
||||
}
|
||||
|
||||
/* align up */
|
||||
fu_byte_array_set_size (buf,
|
||||
fu_common_align_up (buf->len,
|
||||
fu_firmware_get_alignment (firmware)));
|
||||
|
||||
/* success */
|
||||
return g_byte_array_free_to_bytes (g_steal_pointer (&buf));
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ifd_bios_init (FuIfdBios *self)
|
||||
{
|
||||
@ -115,7 +91,6 @@ fu_ifd_bios_class_init (FuIfdBiosClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_ifd_bios_parse;
|
||||
klass_firmware->write = fu_ifd_bios_write;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,43 +61,38 @@ G_DEFINE_TYPE_WITH_PRIVATE (FuIfdFirmware, fu_ifd_firmware, FU_TYPE_FIRMWARE)
|
||||
#define FU_IFD_FREG_LIMIT(freg) ((((freg) >> 4) & 0x07FFF000) | 0x00000FFF)
|
||||
|
||||
static void
|
||||
fu_ifd_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_ifd_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuIfdFirmware *self = FU_IFD_FIRMWARE (firmware);
|
||||
FuIfdFirmwarePrivate *priv = GET_PRIVATE (self);
|
||||
fu_common_string_append_kx (str, idt, "DescriptorMap0",
|
||||
priv->descriptor_map0);
|
||||
fu_common_string_append_kx (str, idt, "DescriptorMap1",
|
||||
priv->descriptor_map1);
|
||||
fu_common_string_append_kx (str, idt, "DescriptorMap2",
|
||||
priv->descriptor_map2);
|
||||
fu_common_string_append_ku (str, idt, "NumRegions",
|
||||
priv->num_regions);
|
||||
fu_common_string_append_ku (str, idt, "NumComponents",
|
||||
priv->num_components + 1);
|
||||
fu_common_string_append_kx (str, idt, "FlashRegionBaseAddr",
|
||||
priv->flash_region_base_addr);
|
||||
fu_common_string_append_kx (str, idt, "FlashComponentBaseAddr",
|
||||
priv->flash_component_base_addr);
|
||||
fu_common_string_append_kx (str, idt, "FlashMasterBaseAddr",
|
||||
priv->flash_master_base_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "descriptor_map0", priv->descriptor_map0);
|
||||
fu_xmlb_builder_insert_kx (bn, "descriptor_map1", priv->descriptor_map1);
|
||||
fu_xmlb_builder_insert_kx (bn, "descriptor_map2", priv->descriptor_map2);
|
||||
fu_xmlb_builder_insert_kx (bn, "num_regions", priv->num_regions);
|
||||
fu_xmlb_builder_insert_kx (bn, "num_components", priv->num_components + 1);
|
||||
fu_xmlb_builder_insert_kx (bn, "flash_region_base_addr", priv->flash_region_base_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "flash_component_base_addr", priv->flash_component_base_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "flash_master_base_addr", priv->flash_master_base_addr);
|
||||
for (guint i = 1; i < 3; i++) {
|
||||
g_autofree gchar *title = g_strdup_printf ("FlashMaster%x", i + 1);
|
||||
fu_common_string_append_kx (str, idt, title,
|
||||
priv->flash_master[i]);
|
||||
fu_xmlb_builder_insert_kx (bn, title, priv->flash_master[i]);
|
||||
}
|
||||
fu_common_string_append_kx (str, idt, "FlashIchStrapBaseAddr",
|
||||
priv->flash_ich_strap_base_addr);
|
||||
fu_common_string_append_kx (str, idt, "FlashMchStrapBaseAddr",
|
||||
priv->flash_mch_strap_base_addr);
|
||||
fu_common_string_append_kx (str, idt, "ComponentsRcd",
|
||||
priv->components_rcd);
|
||||
fu_common_string_append_kx (str, idt, "IllegalJedec", priv->illegal_jedec);
|
||||
fu_common_string_append_kx (str, idt, "IllegalJedec1", priv->illegal_jedec1);
|
||||
if (priv->flash_descriptor_regs != NULL) {
|
||||
for (guint i = 0; i < priv->num_regions; i++) {
|
||||
g_autofree gchar *title = g_strdup_printf ("FlashDescriptorReg%x", i);
|
||||
fu_common_string_append_kx (str, idt, title, priv->flash_descriptor_regs[i]);
|
||||
fu_xmlb_builder_insert_kx (bn, "flash_ich_strap_base_addr",
|
||||
priv->flash_ich_strap_base_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "flash_mch_strap_base_addr",
|
||||
priv->flash_mch_strap_base_addr);
|
||||
fu_xmlb_builder_insert_kx (bn, "components_rcd",
|
||||
priv->components_rcd);
|
||||
fu_xmlb_builder_insert_kx (bn, "illegal_jedec", priv->illegal_jedec);
|
||||
fu_xmlb_builder_insert_kx (bn, "illegal_jedec1", priv->illegal_jedec1);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
if (priv->flash_descriptor_regs != NULL) {
|
||||
for (guint i = 0; i < priv->num_regions; i++) {
|
||||
g_autofree gchar *title = g_strdup_printf ("flash_descriptor_reg%x", i);
|
||||
fu_xmlb_builder_insert_kx (bn, title, priv->flash_descriptor_regs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -474,7 +469,7 @@ fu_ifd_firmware_class_init (FuIfdFirmwareClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
object_class->finalize = fu_ifd_firmware_finalize;
|
||||
klass_firmware->to_string = fu_ifd_firmware_to_string;
|
||||
klass_firmware->export = fu_ifd_firmware_export;
|
||||
klass_firmware->parse = fu_ifd_firmware_parse;
|
||||
klass_firmware->write = fu_ifd_firmware_write;
|
||||
klass_firmware->build = fu_ifd_firmware_build;
|
||||
|
@ -18,17 +18,19 @@ G_DEFINE_TYPE_WITH_PRIVATE (FuIfdImage, fu_ifd_image, FU_TYPE_FIRMWARE)
|
||||
#define GET_PRIVATE(o) (fu_ifd_image_get_instance_private (o))
|
||||
|
||||
static void
|
||||
fu_ifd_image_to_string (FuFirmware *image, guint idt, GString *str)
|
||||
fu_ifd_image_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuIfdImage *self = FU_IFD_IMAGE (image);
|
||||
FuIfdImage *self = FU_IFD_IMAGE (firmware);
|
||||
FuIfdImagePrivate *priv = GET_PRIVATE (self);
|
||||
for (guint i = 0; i < FU_IFD_REGION_MAX; i++) {
|
||||
g_autofree gchar *title = NULL;
|
||||
if (priv->access[i] == FU_IFD_ACCESS_NONE)
|
||||
continue;
|
||||
title = g_strdup_printf ("Access[%s]", fu_ifd_region_to_string (i));
|
||||
fu_common_string_append_kv (str, idt, title,
|
||||
fu_ifd_access_to_string (priv->access[i]));
|
||||
xb_builder_node_insert_text (bn, "access",
|
||||
fu_ifd_access_to_string (priv->access[i]),
|
||||
"region", fu_ifd_region_to_string (i),
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,19 +73,32 @@ static GBytes *
|
||||
fu_ifd_image_write (FuFirmware *firmware, GError **error)
|
||||
{
|
||||
g_autoptr(GByteArray) buf = g_byte_array_new ();
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
g_autoptr(GPtrArray) images = fu_firmware_get_images (firmware);
|
||||
|
||||
/* simple payload */
|
||||
bytes = fu_firmware_get_bytes (firmware, error);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
fu_byte_array_append_bytes (buf, bytes);
|
||||
/* add each volume */
|
||||
if (images->len > 0) {
|
||||
for (guint i = 0; i < images->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index (images, i);
|
||||
g_autoptr(GBytes) bytes = fu_firmware_write (img, error);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
fu_byte_array_append_bytes (buf, bytes);
|
||||
}
|
||||
} else {
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
bytes = fu_firmware_get_bytes (firmware, error);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
fu_byte_array_append_bytes (buf, bytes);
|
||||
}
|
||||
|
||||
/* align up */
|
||||
fu_byte_array_set_size (buf,
|
||||
fu_common_align_up (g_bytes_get_size (bytes),
|
||||
fu_firmware_get_alignment (firmware)));
|
||||
fu_byte_array_set_size (buf, fu_common_align_up (buf->len,
|
||||
fu_firmware_get_alignment (firmware)));
|
||||
|
||||
/* success */
|
||||
return g_byte_array_free_to_bytes (g_steal_pointer (&buf));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -96,7 +111,7 @@ static void
|
||||
fu_ifd_image_class_init (FuIfdImageClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_image = FU_FIRMWARE_CLASS (klass);
|
||||
klass_image->to_string = fu_ifd_image_to_string;
|
||||
klass_image->export = fu_ifd_image_export;
|
||||
klass_image->write = fu_ifd_image_write;
|
||||
}
|
||||
|
||||
|
212
plugins/spi/fu-self-test.c
Normal file
212
plugins/spi/fu-self-test.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-efi-firmware-file.h"
|
||||
#include "fu-efi-firmware-filesystem.h"
|
||||
#include "fu-efi-firmware-section.h"
|
||||
#include "fu-efi-firmware-volume.h"
|
||||
#include "fu-ifd-bios.h"
|
||||
#include "fu-ifd-image.h"
|
||||
|
||||
static void
|
||||
fu_efi_firmware_section_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_efi_firmware_section_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_efi_firmware_section_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/efi-firmware-section.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_efi_firmware_file_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_efi_firmware_file_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_efi_firmware_file_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/efi-firmware-file.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "fb0f4b276b3672d2dbcf3fe543ddd743f02c7fe0");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_efi_firmware_filesystem_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_efi_firmware_filesystem_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_efi_firmware_filesystem_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/efi-firmware-filesystem.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "d6fbadc1c303a3b4eede9db7fb0ddb353efffc86");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_efi_firmware_volume_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_efi_firmware_volume_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_efi_firmware_volume_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/efi-firmware-volume.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ifd_image_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_ifd_image_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_ifd_image_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/ifd.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "49e18145664a6910ba86b5e6ce74e40efd76c963");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_type_ensure (FU_TYPE_IFD_BIOS);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/efi/firmware-section{xml}", fu_efi_firmware_section_xml_func);
|
||||
g_test_add_func ("/efi/firmware-file{xml}", fu_efi_firmware_file_xml_func);
|
||||
g_test_add_func ("/efi/firmware-filesystem{xml}", fu_efi_firmware_filesystem_xml_func);
|
||||
g_test_add_func ("/efi/firmware-volume{xml}", fu_efi_firmware_volume_xml_func);
|
||||
g_test_add_func ("/ifd/image{xml}", fu_ifd_image_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
@ -34,3 +34,39 @@ shared_module('fu_plugin_spi',
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tests') and get_option('lzma')
|
||||
e = executable(
|
||||
'spi-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-efi-common.c',
|
||||
'fu-efi-firmware-common.c',
|
||||
'fu-efi-firmware-file.c',
|
||||
'fu-efi-firmware-filesystem.c',
|
||||
'fu-efi-firmware-section.c',
|
||||
'fu-efi-firmware-volume.c',
|
||||
'fu-ifd-bios.c',
|
||||
'fu-ifd-common.c',
|
||||
'fu-ifd-firmware.c',
|
||||
'fu-ifd-image.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
lzma,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
install : true,
|
||||
install_dir : installed_test_bindir,
|
||||
)
|
||||
test('spi-self-test', e)
|
||||
endif
|
||||
|
@ -44,17 +44,19 @@ fu_synaptics_cxaudio_firmware_get_layout_version (FuSynapticsCxaudioFirmware *se
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_cxaudio_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_synaptics_cxaudio_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuSynapticsCxaudioFirmware *self = FU_SYNAPTICS_CXAUDIO_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "FileKind", self->file_kind);
|
||||
fu_common_string_append_kx (str, idt, "DeviceKind", self->device_kind);
|
||||
fu_common_string_append_kx (str, idt, "LayoutSignature", self->cinfo.LayoutSignature);
|
||||
fu_common_string_append_kx (str, idt, "LayoutVersion", self->cinfo.LayoutVersion);
|
||||
fu_xmlb_builder_insert_kx (bn, "file_kind", self->file_kind);
|
||||
fu_xmlb_builder_insert_kx (bn, "device_kind", self->device_kind);
|
||||
fu_xmlb_builder_insert_kx (bn, "layout_signature", self->cinfo.LayoutSignature);
|
||||
fu_xmlb_builder_insert_kx (bn, "layout_version", self->cinfo.LayoutVersion);
|
||||
if (self->cinfo.LayoutVersion >= 1) {
|
||||
fu_common_string_append_kx (str, idt, "VendorID", self->cinfo.VendorID);
|
||||
fu_common_string_append_kx (str, idt, "ProductID", self->cinfo.ProductID);
|
||||
fu_common_string_append_kx (str, idt, "RevisionID", self->cinfo.RevisionID);
|
||||
fu_xmlb_builder_insert_kx (bn, "vid", self->cinfo.VendorID);
|
||||
fu_xmlb_builder_insert_kx (bn, "pid", self->cinfo.ProductID);
|
||||
fu_xmlb_builder_insert_kx (bn, "rev", self->cinfo.RevisionID);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +296,7 @@ fu_synaptics_cxaudio_firmware_class_init (FuSynapticsCxaudioFirmwareClass *klass
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_synaptics_cxaudio_firmware_parse;
|
||||
klass_firmware->to_string = fu_synaptics_cxaudio_firmware_to_string;
|
||||
klass_firmware->export = fu_synaptics_cxaudio_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <glib/gstdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fu-synaptics-mst-firmware.h"
|
||||
|
||||
#include "fu-plugin-private.h"
|
||||
|
||||
static void
|
||||
@ -129,6 +131,42 @@ fu_plugin_synaptics_mst_tb16_func (void)
|
||||
g_assert_cmpint (devices->len, ==, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_mst_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_synaptics_mst_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_synaptics_mst_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/synaptics-mst.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "bfcdf3e6ca6cef45543bfbb57509c92aec9a39fb");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -142,5 +180,7 @@ main (int argc, char **argv)
|
||||
/* tests go here */
|
||||
g_test_add_func ("/fwupd/plugin/synaptics_mst{none}", fu_plugin_synaptics_mst_none_func);
|
||||
g_test_add_func ("/fwupd/plugin/synaptics_mst{tb16}", fu_plugin_synaptics_mst_tb16_func);
|
||||
g_test_add_func ("/fwupd/plugin/synaptics_mst/firmware{xml}", fu_synaptics_mst_firmware_xml_func);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -26,10 +26,12 @@ fu_synaptics_mst_firmware_get_board_id (FuSynapticsMstFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_mst_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_synaptics_mst_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuSynapticsMstFirmware *self = FU_SYNAPTICS_MST_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "BoardId", self->board_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "board_id", self->board_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -75,6 +77,21 @@ fu_synaptics_mst_firmware_write (FuFirmware *firmware, GError **error)
|
||||
return g_byte_array_free_to_bytes (g_steal_pointer (&buf));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_synaptics_rmi_firmware_build (FuFirmware *firmware, XbNode *n, GError **error)
|
||||
{
|
||||
FuSynapticsMstFirmware *self = FU_SYNAPTICS_MST_FIRMWARE (firmware);
|
||||
guint64 tmp;
|
||||
|
||||
/* optional properties */
|
||||
tmp = xb_node_query_text_as_uint (n, "board_id", NULL);
|
||||
if (tmp != G_MAXUINT64)
|
||||
self->board_id = tmp;
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_mst_firmware_init (FuSynapticsMstFirmware *self)
|
||||
{
|
||||
@ -85,8 +102,9 @@ fu_synaptics_mst_firmware_class_init (FuSynapticsMstFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_synaptics_mst_firmware_parse;
|
||||
klass_firmware->to_string = fu_synaptics_mst_firmware_to_string;
|
||||
klass_firmware->export = fu_synaptics_mst_firmware_export;
|
||||
klass_firmware->write = fu_synaptics_mst_firmware_write;
|
||||
klass_firmware->build = fu_synaptics_rmi_firmware_build;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -78,11 +78,48 @@ fu_test_synaprom_firmware_func (void)
|
||||
g_assert_cmpint (buf[1], ==, 'H');
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaprom_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_synaprom_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_synaprom_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/synaprom.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
g_test_add_func ("/synaprom/firmware", fu_test_synaprom_firmware_func);
|
||||
g_test_add_func ("/synaprom/firmware{xml}", fu_synaprom_firmware_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -51,10 +51,12 @@ fu_synaprom_firmware_tag_to_string (guint16 tag)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaprom_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_synaprom_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuSynapromFirmware *self = FU_SYNAPROM_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "ProductId", self->product_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "product_id", self->product_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -220,7 +222,7 @@ fu_synaprom_firmware_class_init (FuSynapromFirmwareClass *klass)
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_synaprom_firmware_parse;
|
||||
klass_firmware->write = fu_synaprom_firmware_write;
|
||||
klass_firmware->to_string = fu_synaprom_firmware_to_string;
|
||||
klass_firmware->export = fu_synaprom_firmware_export;
|
||||
klass_firmware->build = fu_synaprom_firmware_build;
|
||||
}
|
||||
|
||||
|
59
plugins/synaptics-rmi/fu-self-test.c
Normal file
59
plugins/synaptics-rmi/fu-self-test.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-synaptics-rmi-firmware.h"
|
||||
|
||||
static void
|
||||
fu_synaptics_rmi_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_synaptics_rmi_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_synaptics_rmi_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/synaptics-rmi.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/synaptics-rmi/firmware{xml}", fu_synaptics_rmi_firmware_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
@ -166,18 +166,23 @@ fu_synaptics_rmi_firmware_add_image (FuFirmware *firmware, const gchar *id,
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_rmi_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_synaptics_rmi_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuSynapticsRmiFirmware *self = FU_SYNAPTICS_RMI_FIRMWARE (firmware);
|
||||
fu_common_string_append_kx (str, idt, "Kind", self->kind);
|
||||
fu_common_string_append_kv (str, idt, "ProductId", self->product_id);
|
||||
fu_common_string_append_kx (str, idt, "BootloaderVersion", self->bootloader_version);
|
||||
fu_common_string_append_kx (str, idt, "IO", self->io);
|
||||
fu_common_string_append_kx (str, idt, "Checksum", self->checksum);
|
||||
fu_common_string_append_kx (str, idt, "BuildId", self->build_id);
|
||||
fu_common_string_append_kx (str, idt, "PackageId", self->package_id);
|
||||
fu_common_string_append_kx (str, idt, "ProductInfo", self->product_info);
|
||||
fu_common_string_append_kx (str, idt, "SigSize", self->sig_size);
|
||||
fu_xmlb_builder_insert_kx (bn, "kind", self->kind);
|
||||
fu_xmlb_builder_insert_kv (bn, "product_id", self->product_id);
|
||||
if (flags & FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG) {
|
||||
fu_xmlb_builder_insert_kx (bn, "bootloader_version",
|
||||
self->bootloader_version);
|
||||
fu_xmlb_builder_insert_kx (bn, "io", self->io);
|
||||
fu_xmlb_builder_insert_kx (bn, "checksum", self->checksum);
|
||||
fu_xmlb_builder_insert_kx (bn, "build_id", self->build_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "package_id", self->package_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "product_info", self->product_info);
|
||||
fu_xmlb_builder_insert_kx (bn, "sig_size", self->sig_size);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -693,7 +698,7 @@ fu_synaptics_rmi_firmware_class_init (FuSynapticsRmiFirmwareClass *klass)
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
object_class->finalize = fu_synaptics_rmi_firmware_finalize;
|
||||
klass_firmware->parse = fu_synaptics_rmi_firmware_parse;
|
||||
klass_firmware->to_string = fu_synaptics_rmi_firmware_to_string;
|
||||
klass_firmware->export = fu_synaptics_rmi_firmware_export;
|
||||
klass_firmware->build = fu_synaptics_rmi_firmware_build;
|
||||
klass_firmware->write = fu_synaptics_rmi_firmware_write;
|
||||
}
|
||||
|
@ -39,3 +39,31 @@ shared_module('fu_plugin_synaptics_rmi',
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tests')
|
||||
e = executable(
|
||||
'synaptics-rmi-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-synaptics-rmi-common.c',
|
||||
'fu-synaptics-rmi-firmware.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
gnutls,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
install : true,
|
||||
install_dir : installed_test_bindir,
|
||||
)
|
||||
test('synaptics-rmi-self-test', e)
|
||||
endif
|
||||
|
@ -127,25 +127,28 @@ fu_thunderbolt_firmware_family_to_string (FuThunderboltFamily family)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_thunderbolt_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_thunderbolt_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuThunderboltFirmware *self = FU_THUNDERBOLT_FIRMWARE (firmware);
|
||||
FuThunderboltFirmwarePrivate *priv = GET_PRIVATE (self);
|
||||
g_autoptr(XbBuilderNode) bc = NULL;
|
||||
|
||||
fu_common_string_append_kv (str, idt, "Family",
|
||||
fu_thunderbolt_firmware_family_to_string (priv->family));
|
||||
fu_common_string_append_kb (str, idt, "IsHost", priv->is_host);
|
||||
fu_common_string_append_kb (str, idt, "IsNative", priv->is_native);
|
||||
fu_common_string_append_kx (str, idt, "DeviceId", priv->device_id);
|
||||
fu_common_string_append_kx (str, idt, "VendorId", priv->vendor_id);
|
||||
fu_common_string_append_kx (str, idt, "ModelId", priv->model_id);
|
||||
fu_common_string_append_kx (str, idt, "FlashSize", priv->flash_size);
|
||||
fu_common_string_append_kx (str, idt, "Generation", priv->gen);
|
||||
fu_common_string_append_kx (str, idt, "Ports", priv->ports);
|
||||
fu_common_string_append_kb (str, idt, "HasPd", priv->has_pd);
|
||||
fu_xmlb_builder_insert_kv (bn, "family",
|
||||
fu_thunderbolt_firmware_family_to_string (priv->family));
|
||||
fu_xmlb_builder_insert_kb (bn, "is_host", priv->is_host);
|
||||
fu_xmlb_builder_insert_kb (bn, "is_native", priv->is_native);
|
||||
fu_xmlb_builder_insert_kx (bn, "device_id", priv->device_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "vendor_id", priv->vendor_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "model_id", priv->model_id);
|
||||
fu_xmlb_builder_insert_kx (bn, "flash_size", priv->flash_size);
|
||||
fu_xmlb_builder_insert_kx (bn, "generation", priv->gen);
|
||||
fu_xmlb_builder_insert_kx (bn, "ports", priv->ports);
|
||||
fu_xmlb_builder_insert_kb (bn, "has_pd", priv->has_pd);
|
||||
for (guint i = 0; i < _SECTION_LAST; i++) {
|
||||
g_autofree gchar *title = g_strdup_printf ("Section%u", i);
|
||||
fu_common_string_append_kx (str, idt, title, priv->sections[i]);
|
||||
g_autofree gchar *tmp = g_strdup_printf ("%x", priv->sections[i]);
|
||||
xb_builder_node_insert_text (bn, "section", tmp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,7 +558,7 @@ fu_thunderbolt_firmware_class_init (FuThunderboltFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_thunderbolt_firmware_parse;
|
||||
klass_firmware->to_string = fu_thunderbolt_firmware_to_string;
|
||||
klass_firmware->export = fu_thunderbolt_firmware_export;
|
||||
}
|
||||
|
||||
FuThunderboltFirmware *
|
||||
|
@ -54,15 +54,15 @@ fu_vli_pd_firmware_validate_header (FuVliPdFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_vli_pd_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_vli_pd_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuVliPdFirmware *self = FU_VLI_PD_FIRMWARE (firmware);
|
||||
fu_common_string_append_kv (str, idt, "DeviceKind",
|
||||
fu_vli_common_device_kind_to_string (self->device_kind));
|
||||
fu_common_string_append_kx (str, idt, "VID",
|
||||
fu_vli_pd_firmware_get_vid (self));
|
||||
fu_common_string_append_kx (str, idt, "PID",
|
||||
fu_vli_pd_firmware_get_pid (self));
|
||||
fu_xmlb_builder_insert_kv (bn, "device_kind",
|
||||
fu_vli_common_device_kind_to_string (self->device_kind));
|
||||
fu_xmlb_builder_insert_kx (bn, "vid", fu_vli_pd_firmware_get_vid (self));
|
||||
fu_xmlb_builder_insert_kx (bn, "pid", fu_vli_pd_firmware_get_pid (self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -167,7 +167,7 @@ fu_vli_pd_firmware_class_init (FuVliPdFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_vli_pd_firmware_parse;
|
||||
klass_firmware->to_string = fu_vli_pd_firmware_to_string;
|
||||
klass_firmware->export = fu_vli_pd_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -16,29 +16,45 @@ fu_vli_usbhub_header_crc8 (FuVliUsbhubHeader *hdr)
|
||||
}
|
||||
|
||||
void
|
||||
fu_vli_usbhub_header_to_string (FuVliUsbhubHeader *hdr, guint idt, GString *str)
|
||||
fu_vli_usbhub_header_export (FuVliUsbhubHeader *hdr, XbBuilderNode *bn)
|
||||
{
|
||||
fu_common_string_append_kx (str, idt, "DevId", GUINT16_FROM_BE(hdr->dev_id));
|
||||
fu_common_string_append_kx (str, idt, "Variant", hdr->variant);
|
||||
fu_xmlb_builder_insert_kx (bn, "dev_id", GUINT16_FROM_BE(hdr->dev_id));
|
||||
fu_xmlb_builder_insert_kx (bn, "variant", hdr->variant);
|
||||
if (hdr->usb2_fw_sz > 0) {
|
||||
fu_common_string_append_kx (str, idt, "Usb2FwAddr",
|
||||
GUINT16_FROM_BE(hdr->usb2_fw_addr));
|
||||
fu_common_string_append_kx (str, idt, "Usb2FwSz",
|
||||
GUINT16_FROM_BE(hdr->usb2_fw_sz));
|
||||
fu_xmlb_builder_insert_kx (bn, "usb2_fw_addr",
|
||||
GUINT16_FROM_BE(hdr->usb2_fw_addr));
|
||||
fu_xmlb_builder_insert_kx (bn, "usb2_fw_sz",
|
||||
GUINT16_FROM_BE(hdr->usb2_fw_sz));
|
||||
}
|
||||
fu_common_string_append_kx (str, idt, "Usb3FwAddr",
|
||||
((guint32) hdr->usb3_fw_addr_high) << 16 |
|
||||
GUINT16_FROM_BE(hdr->usb3_fw_addr));
|
||||
fu_common_string_append_kx (str, idt, "Usb3FwSz",
|
||||
GUINT16_FROM_BE(hdr->usb3_fw_sz));
|
||||
fu_xmlb_builder_insert_kx (bn, "usb3_fw_addr",
|
||||
((guint32) hdr->usb3_fw_addr_high) << 16 |
|
||||
GUINT16_FROM_BE(hdr->usb3_fw_addr));
|
||||
fu_xmlb_builder_insert_kx (bn, "usb3_fw_sz",
|
||||
GUINT16_FROM_BE(hdr->usb3_fw_sz));
|
||||
if (hdr->prev_ptr != VLI_USBHUB_FLASHMAP_IDX_INVALID) {
|
||||
fu_common_string_append_kx (str, idt, "PrevPtr",
|
||||
VLI_USBHUB_FLASHMAP_IDX_TO_ADDR(hdr->prev_ptr));
|
||||
fu_xmlb_builder_insert_kx (bn, "prev_ptr",
|
||||
VLI_USBHUB_FLASHMAP_IDX_TO_ADDR(hdr->prev_ptr));
|
||||
}
|
||||
if (hdr->next_ptr != VLI_USBHUB_FLASHMAP_IDX_INVALID) {
|
||||
fu_common_string_append_kx (str, idt, "NextPtr",
|
||||
VLI_USBHUB_FLASHMAP_IDX_TO_ADDR(hdr->next_ptr));
|
||||
fu_xmlb_builder_insert_kx (bn, "next_ptr",
|
||||
VLI_USBHUB_FLASHMAP_IDX_TO_ADDR(hdr->next_ptr));
|
||||
}
|
||||
fu_common_string_append_kb (str, idt, "ChecksumOK",
|
||||
hdr->checksum == fu_vli_usbhub_header_crc8 (hdr));
|
||||
fu_xmlb_builder_insert_kb (bn, "checksum_ok",
|
||||
hdr->checksum == fu_vli_usbhub_header_crc8 (hdr));
|
||||
}
|
||||
|
||||
void
|
||||
fu_vli_usbhub_header_to_string (FuVliUsbhubHeader *hdr, guint idt, GString *str)
|
||||
{
|
||||
g_autoptr(XbBuilderNode) bn = xb_builder_node_new ("header");
|
||||
g_autofree gchar *xml = NULL;
|
||||
fu_vli_usbhub_header_export (hdr, bn);
|
||||
xml = xb_builder_node_export (bn,
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_MULTILINE |
|
||||
#if LIBXMLB_CHECK_VERSION(0,2,2)
|
||||
XB_NODE_EXPORT_FLAG_COLLAPSE_EMPTY |
|
||||
#endif
|
||||
XB_NODE_EXPORT_FLAG_FORMAT_INDENT,
|
||||
NULL);
|
||||
fu_common_string_append_kv (str, idt, "xml", xml);
|
||||
}
|
||||
|
@ -63,3 +63,5 @@ guint8 fu_vli_usbhub_header_crc8 (FuVliUsbhubHeader *hdr);
|
||||
void fu_vli_usbhub_header_to_string (FuVliUsbhubHeader *hdr,
|
||||
guint idt,
|
||||
GString *str);
|
||||
void fu_vli_usbhub_header_export (FuVliUsbhubHeader *hdr,
|
||||
XbBuilderNode *bn);
|
||||
|
@ -34,12 +34,14 @@ fu_vli_usbhub_firmware_get_device_id (FuVliUsbhubFirmware *self)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_vli_usbhub_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
|
||||
fu_vli_usbhub_firmware_export (FuFirmware *firmware,
|
||||
FuFirmwareExportFlags flags,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuVliUsbhubFirmware *self = FU_VLI_USBHUB_FIRMWARE (firmware);
|
||||
fu_common_string_append_kv (str, idt, "DeviceKind",
|
||||
fu_vli_common_device_kind_to_string (self->device_kind));
|
||||
fu_vli_usbhub_header_to_string (&self->hdr, idt, str);
|
||||
fu_xmlb_builder_insert_kv (bn, "device_kind",
|
||||
fu_vli_common_device_kind_to_string (self->device_kind));
|
||||
fu_vli_usbhub_header_export (&self->hdr, bn);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -213,7 +215,7 @@ fu_vli_usbhub_firmware_class_init (FuVliUsbhubFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_vli_usbhub_firmware_parse;
|
||||
klass_firmware->to_string = fu_vli_usbhub_firmware_to_string;
|
||||
klass_firmware->export = fu_vli_usbhub_firmware_export;
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-srec-firmware.h"
|
||||
#include "fu-wac-common.h"
|
||||
#include "fu-wac-firmware.h"
|
||||
|
||||
@ -52,11 +53,47 @@ fu_wac_firmware_parse_func (void)
|
||||
g_bytes_get_data (blob_block, NULL),
|
||||
g_bytes_get_size (blob_block));
|
||||
}
|
||||
static void
|
||||
fu_wac_firmware_xml_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *csum1 = NULL;
|
||||
g_autofree gchar *csum2 = NULL;
|
||||
g_autofree gchar *xml_out = NULL;
|
||||
g_autofree gchar *xml_src = NULL;
|
||||
g_autoptr(FuFirmware) firmware1 = fu_wac_firmware_new ();
|
||||
g_autoptr(FuFirmware) firmware2 = fu_wac_firmware_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* build and write */
|
||||
ret = g_file_get_contents (FWUPD_FUZZINGSRCDIR "/wacom.builder.xml",
|
||||
&xml_src, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
ret = fu_firmware_build_from_xml (firmware1, xml_src, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum1 = fu_firmware_get_checksum (firmware1, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (csum1, ==, "bd734911430831127a7bba4664e212a56a2821bc");
|
||||
|
||||
/* ensure we can round-trip */
|
||||
xml_out = fu_firmware_export_to_xml (firmware1,
|
||||
FU_FIRMWARE_EXPORT_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
ret = fu_firmware_build_from_xml (firmware2, xml_out, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
csum2 = fu_firmware_get_checksum (firmware2, G_CHECKSUM_SHA1, &error);
|
||||
g_assert_cmpstr (csum1, ==, csum2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_type_ensure (FU_TYPE_SREC_FIRMWARE);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
@ -66,6 +103,7 @@ main (int argc, char **argv)
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/wac/firmware{parse}", fu_wac_firmware_parse_func);
|
||||
g_test_add_func ("/wac/firmware{xml}", fu_wac_firmware_xml_func);
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
@ -1939,6 +1939,62 @@ fu_util_firmware_parse (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_firmware_export (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
FuFirmwareExportFlags flags = FU_FIRMWARE_EXPORT_FLAG_NONE;
|
||||
GType gtype;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(FuFirmware) firmware = NULL;
|
||||
g_autofree gchar *firmware_type = NULL;
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
/* check args */
|
||||
if (g_strv_length (values) == 0 || g_strv_length (values) > 2) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_ARGS,
|
||||
"Invalid arguments: filename required");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_strv_length (values) == 2)
|
||||
firmware_type = g_strdup (values[1]);
|
||||
|
||||
/* load file */
|
||||
blob = fu_common_get_contents_bytes (values[0], error);
|
||||
if (blob == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* load engine */
|
||||
if (!fu_engine_load (priv->engine, FU_ENGINE_LOAD_FLAG_READONLY, error))
|
||||
return FALSE;
|
||||
|
||||
/* find the GType to use */
|
||||
if (firmware_type == NULL)
|
||||
firmware_type = fu_util_prompt_for_firmware_type (priv, error);
|
||||
if (firmware_type == NULL)
|
||||
return FALSE;
|
||||
gtype = fu_engine_get_firmware_gtype_by_id (priv->engine, firmware_type);
|
||||
if (gtype == G_TYPE_INVALID) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"GType %s not supported", firmware_type);
|
||||
return FALSE;
|
||||
}
|
||||
firmware = g_object_new (gtype, NULL);
|
||||
if (!fu_firmware_parse (firmware, blob, priv->flags, error))
|
||||
return FALSE;
|
||||
if (priv->show_all)
|
||||
flags |= FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG;
|
||||
str = fu_firmware_export_to_xml (firmware, flags, error);
|
||||
if (str == NULL)
|
||||
return FALSE;
|
||||
g_print ("%s", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_firmware_extract (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
@ -3010,6 +3066,13 @@ main (int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Parse and show details about a firmware file"),
|
||||
fu_util_firmware_parse);
|
||||
fu_util_cmd_array_add (cmd_array,
|
||||
"firmware-export",
|
||||
/* TRANSLATORS: command argument: uppercase, spaces->dashes */
|
||||
_("FILENAME [FIRMWARE-TYPE]"),
|
||||
/* TRANSLATORS: command description */
|
||||
_("Export a firmware file structure to XML"),
|
||||
fu_util_firmware_export);
|
||||
fu_util_cmd_array_add (cmd_array,
|
||||
"firmware-extract",
|
||||
/* TRANSLATORS: command argument: uppercase, spaces->dashes */
|
||||
|
7
src/fuzzing/efi-firmware-file.builder.xml
Normal file
7
src/fuzzing/efi-firmware-file.builder.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<firmware gtype="FuEfiFirmwareFile">
|
||||
<id>ced4eac6-49f3-4c12-a597-fc8c33447691</id>
|
||||
<type>0x0B</type>
|
||||
<firmware gtype="FuEfiFirmwareSection">
|
||||
<data>aGVsbG8gd29ybGQ=</data>
|
||||
</firmware>
|
||||
</firmware>
|
5
src/fuzzing/efi-firmware-section.builder.xml
Normal file
5
src/fuzzing/efi-firmware-section.builder.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<firmware gtype="FuEfiFirmwareSection">
|
||||
<type>0x02</type>
|
||||
<id>ced4eac6-49f3-4c12-a597-fc8c33447691</id>
|
||||
<data>aGVsbG8gd29ybGQ=</data>
|
||||
</firmware>
|
BIN
src/fuzzing/firmware/efi-file.bin
Normal file
BIN
src/fuzzing/firmware/efi-file.bin
Normal file
Binary file not shown.
4
src/fuzzing/synaptics-rmi.builder.xml
Normal file
4
src/fuzzing/synaptics-rmi.builder.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<firmware gtype="FuSynapticsMstFirmware">
|
||||
<board_id>0x42</board_id>
|
||||
<data>aGVsbG8gd29ybGQ=</data> <!-- base64 -->
|
||||
</firmware>
|
Loading…
Reference in New Issue
Block a user