Don't use AppStream-glib for the GUID helpers

Long term we want to wean ourselves away from libappstream-glib.
This commit is contained in:
Richard Hughes 2018-10-10 20:01:05 +01:00
parent bcf875ff3b
commit d3d2c2c39f
10 changed files with 209 additions and 23 deletions

View File

@ -13,6 +13,7 @@
#include <unistd.h>
#include <fcntl.h>
#include "fu-common-guid.h"
#include "fu-plugin-dell.h"
#include "fu-plugin-vfuncs.h"
#include "fu-device-metadata.h"
@ -597,11 +598,11 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error)
}
tpm_guid_raw = g_strdup_printf ("%04x-%s", system_id, tpm_mode);
tpm_guid = as_utils_guid_from_string (tpm_guid_raw);
tpm_guid = fu_common_guid_from_string (tpm_guid_raw);
tpm_id = g_strdup_printf ("DELL-%s" G_GUINT64_FORMAT, tpm_guid);
tpm_guid_raw_alt = g_strdup_printf ("%04x-%s", system_id, tpm_mode_alt);
tpm_guid_alt = as_utils_guid_from_string (tpm_guid_raw_alt);
tpm_guid_alt = fu_common_guid_from_string (tpm_guid_raw_alt);
tpm_id_alt = g_strdup_printf ("DELL-%s" G_GUINT64_FORMAT, tpm_guid_alt);
g_debug ("Creating primary TPM GUID %s and secondary TPM GUID %s",

View File

@ -7,10 +7,10 @@
#include "config.h"
#include <fwupd.h>
#include <appstream-glib.h>
#include <glib/gstdio.h>
#include <string.h>
#include "fu-common-guid.h"
#include "fu-rom.h"
static void fu_rom_finalize (GObject *object);
@ -689,7 +689,7 @@ fu_rom_load_data (FuRom *self,
/* update guid */
id = g_strdup_printf ("PCI\\VEN_%04X&DEV_%04X",
self->vendor_id, self->device_id);
self->guid = as_utils_guid_from_string (id);
self->guid = fu_common_guid_from_string (id);
g_debug ("using %s for %s", self->guid, id);
/* not known */

129
src/fu-common-guid.c Normal file
View File

@ -0,0 +1,129 @@
/*
* Copyright (C) 2017-2018 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#define G_LOG_DOMAIN "FuCommon"
#include <config.h>
#include <string.h>
#include <uuid.h>
#include "fwupd-error.h"
#include "fu-common-guid.h"
/**
* fu_common_guid_from_data:
* @namespace_id: A namespace ID, e.g. "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
* @data: data to hash
* @data_len: length of @data
* @error: A #GError or %NULL
*
* Returns a GUID for some data. This uses a hash and so even small
* differences in the @data will produce radically different return values.
*
* The implementation is taken from RFC4122, Section 4.1.3; specifically
* using a type-5 SHA-1 hash.
*
* Returns: A new GUID, or %NULL if the namespace_id was invalid
*
* Since: 1.2.0
**/
gchar *
fu_common_guid_from_data (const gchar *namespace_id,
const guint8 *data,
gsize data_len,
GError **error)
{
gchar guid_new[37]; /* 36 plus NUL */
gsize digestlen = 20;
guint8 hash[20];
gint rc;
uuid_t uu_namespace;
uuid_t uu_new;
g_autoptr(GChecksum) csum = NULL;
g_return_val_if_fail (namespace_id != NULL, FALSE);
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data_len != 0, FALSE);
/* convert the namespace to binary */
rc = uuid_parse (namespace_id, uu_namespace);
if (rc != 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"namespace '%s' is invalid",
namespace_id);
return FALSE;
}
/* hash the namespace and then the string */
csum = g_checksum_new (G_CHECKSUM_SHA1);
g_checksum_update (csum, (guchar *) uu_namespace, 16);
g_checksum_update (csum, (guchar *) data, (gssize) data_len);
g_checksum_get_digest (csum, hash, &digestlen);
/* copy most parts of the hash 1:1 */
memcpy (uu_new, hash, 16);
/* set specific bits according to Section 4.1.3 */
uu_new[6] = (guint8) ((uu_new[6] & 0x0f) | (5 << 4));
uu_new[8] = (guint8) ((uu_new[8] & 0x3f) | 0x80);
/* return as a string */
uuid_unparse (uu_new, guid_new);
return g_strdup (guid_new);
}
/**
* fu_common_guid_is_valid:
* @guid: string to check
*
* Checks the source string is a valid string GUID descriptor.
*
* Returns: %TRUE if @guid was a valid GUID, %FALSE otherwise
*
* Since: 1.2.0
**/
gboolean
fu_common_guid_is_valid (const gchar *guid)
{
gint rc;
uuid_t uu;
if (guid == NULL)
return FALSE;
rc = uuid_parse (guid, uu);
return rc == 0;
}
/**
* fu_common_guid_from_string:
* @str: A source string to use as a key
*
* Returns a GUID for a given string. This uses a hash and so even small
* differences in the @str will produce radically different return values.
*
* The implementation is taken from RFC4122, Section 4.1.3; specifically
* using a type-5 SHA-1 hash with a DNS namespace.
* The same result can be obtained with this simple python program:
*
* #!/usr/bin/python
* import uuid
* print uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
*
* Returns: A new GUID, or %NULL if the string was invalid
*
* Since: 1.2.0
**/
gchar *
fu_common_guid_from_string (const gchar *str)
{
if (str == NULL)
return NULL;
return fu_common_guid_from_data ("6ba7b810-9dad-11d1-80b4-00c04fd430c8",
(const guint8 *) str, strlen (str), NULL);
}

19
src/fu-common-guid.h Normal file
View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2017-2018 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef __FU_COMMON_GUID_H__
#define __FU_COMMON_GUID_H__
#include <gio/gio.h>
gboolean fu_common_guid_is_valid (const gchar *guid);
gchar *fu_common_guid_from_string (const gchar *str);
gchar *fu_common_guid_from_data (const gchar *namespace_id,
const guint8 *data,
gsize data_len,
GError **error);
#endif /* __FU_COMMON_GUID_H__ */

View File

@ -13,6 +13,7 @@
#include <gio/gio.h>
#include "fu-common.h"
#include "fu-common-guid.h"
#include "fu-device-private.h"
#include "fu-mutex.h"
@ -534,8 +535,8 @@ fu_device_add_parent_guid (FuDevice *self, const gchar *guid)
g_return_if_fail (guid != NULL);
/* make valid */
if (!as_utils_guid_is_valid (guid)) {
g_autofree gchar *tmp = as_utils_guid_from_string (guid);
if (!fu_common_guid_is_valid (guid)) {
g_autofree gchar *tmp = fu_common_guid_from_string (guid);
if (fu_device_has_parent_guid (self, tmp))
return;
g_debug ("using %s for %s", tmp, guid);
@ -769,7 +770,7 @@ fu_device_add_guid_safe (FuDevice *self, const gchar *guid)
* @guid: A GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad`
*
* Adds a GUID to the device. If the @guid argument is not a valid GUID then it
* is converted to a GUID using as_utils_guid_from_string().
* is converted to a GUID using fu_common_guid_from_string().
*
* Since: 0.7.2
**/
@ -777,8 +778,8 @@ void
fu_device_add_guid (FuDevice *self, const gchar *guid)
{
/* make valid */
if (!as_utils_guid_is_valid (guid)) {
g_autofree gchar *tmp = as_utils_guid_from_string (guid);
if (!fu_common_guid_is_valid (guid)) {
g_autofree gchar *tmp = fu_common_guid_from_string (guid);
g_debug ("using %s for %s", tmp, guid);
fu_device_add_guid_safe (self, tmp);
return;
@ -794,7 +795,7 @@ fu_device_add_guid (FuDevice *self, const gchar *guid)
* @guid: A GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad`
*
* Adds a GUID to the device. If the @guid argument is not a valid GUID then it
* is converted to a GUID using as_utils_guid_from_string().
* is converted to a GUID using fu_common_guid_from_string().
*
* A counterpart GUID is typically the GUID of the same device in bootloader
* or runtime mode, if they have a different device PCI or USB ID. Adding this
@ -806,8 +807,8 @@ void
fu_device_add_counterpart_guid (FuDevice *self, const gchar *guid)
{
/* make valid */
if (!as_utils_guid_is_valid (guid)) {
g_autofree gchar *tmp = as_utils_guid_from_string (guid);
if (!fu_common_guid_is_valid (guid)) {
g_autofree gchar *tmp = fu_common_guid_from_string (guid);
g_debug ("using %s for counterpart %s", tmp, guid);
fwupd_device_add_guid (FWUPD_DEVICE (self), tmp);
return;

View File

@ -25,6 +25,7 @@
#include "fwupd-resources.h"
#include "fu-common-cab.h"
#include "fu-common-guid.h"
#include "fu-common.h"
#include "fu-config.h"
#include "fu-debug.h"
@ -824,7 +825,7 @@ fu_engine_check_requirement_firmware (FuEngine *self, AsRequire *req,
}
/* another device */
if (as_utils_guid_is_valid (as_require_get_value (req))) {
if (fu_common_guid_is_valid (as_require_get_value (req))) {
const gchar *guid = as_require_get_value (req);
const gchar *version;
g_autoptr(FuDevice) device2 = NULL;
@ -996,9 +997,9 @@ fu_engine_vendor_fixup_provide_value (AsApp *app)
g_autofree gchar *guid = NULL;
if (as_provide_get_kind (prov) != AS_PROVIDE_KIND_FIRMWARE_FLASHED)
continue;
if (as_utils_guid_is_valid (value))
if (fu_common_guid_is_valid (value))
continue;
guid = as_utils_guid_from_string (value);
guid = fu_common_guid_from_string (value);
as_provide_set_value (prov, guid);
}
}

View File

@ -11,9 +11,9 @@
#include <glib.h>
#include <gio/gio.h>
#include <string.h>
#include <appstream-glib.h>
#include "fu-common.h"
#include "fu-common-guid.h"
#include "fu-hwids.h"
#include "fwupd-error.h"
@ -97,10 +97,10 @@ fu_hwids_get_guid_for_str (const gchar *str, GError **error)
data[i] = GUINT16_TO_LE(data[i]);
/* convert to a GUID */
return as_utils_guid_from_data (namespace_id,
(guint8*) data,
items_written * 2,
error);
return fu_common_guid_from_data (namespace_id,
(guint8*) data,
items_written * 2,
error);
}
/**

View File

@ -11,9 +11,9 @@
#include <glib-object.h>
#include <gio/gio.h>
#include <string.h>
#include <appstream-glib.h>
#include "fu-common.h"
#include "fu-common-guid.h"
#include "fu-mutex.h"
#include "fu-quirks.h"
@ -97,9 +97,9 @@ fu_quirks_build_group_key (const gchar *group)
for (guint i = 0; guid_prefixes[i] != NULL; i++) {
if (g_str_has_prefix (group, guid_prefixes[i])) {
gsize len = strlen (guid_prefixes[i]);
if (as_utils_guid_is_valid (group + len))
if (fu_common_guid_is_valid (group + len))
return g_strdup (group + len);
return as_utils_guid_from_string (group + len);
return fu_common_guid_from_string (group + len);
}
}

View File

@ -16,6 +16,7 @@
#include <string.h>
#include "fu-common-cab.h"
#include "fu-common-guid.h"
#include "fu-chunk.h"
#include "fu-config.h"
#include "fu-device-list.h"
@ -2838,6 +2839,29 @@ fu_common_strstrip_func (void)
}
}
static void
fu_common_guid_func (void)
{
g_autofree gchar *guid1 = NULL;
g_autofree gchar *guid2 = NULL;
/* invalid */
g_assert (!fu_common_guid_is_valid (NULL));
g_assert (!fu_common_guid_is_valid (""));
g_assert (!fu_common_guid_is_valid ("1ff60ab2-3905-06a1-b476"));
g_assert (!fu_common_guid_is_valid ("1ff60ab2-XXXX-XXXX-XXXX-0371f00c9e9b"));
g_assert (!fu_common_guid_is_valid (" 1ff60ab2-3905-06a1-b476-0371f00c9e9b"));
/* valid */
g_assert (fu_common_guid_is_valid ("1ff60ab2-3905-06a1-b476-0371f00c9e9b"));
/* make valid */
guid1 = fu_common_guid_from_string ("python.org");
g_assert_cmpstr (guid1, ==, "886313e1-3b8a-5372-9b90-0c9aee199e5d");
guid2 = fu_common_guid_from_string ("8086:0406");
g_assert_cmpstr (guid2, ==, "1fbd1f2c-80f4-5d7c-a6ad-35c7b9bd5486");
}
int
main (int argc, char **argv)
{
@ -2899,6 +2923,7 @@ main (int argc, char **argv)
g_test_add_func ("/fwupd/keyring{gpg}", fu_keyring_gpg_func);
g_test_add_func ("/fwupd/keyring{pkcs7}", fu_keyring_pkcs7_func);
g_test_add_func ("/fwupd/chunk", fu_chunk_func);
g_test_add_func ("/fwupd/common{guid}", fu_common_guid_func);
g_test_add_func ("/fwupd/common{strstrip}", fu_common_strstrip_func);
g_test_add_func ("/fwupd/common{endian}", fu_common_endian_func);
g_test_add_func ("/fwupd/common{cab-success}", fu_common_store_cab_func);

View File

@ -26,6 +26,7 @@ libfwupdprivate = static_library(
'fwupdprivate',
sources : [
'fu-common.c',
'fu-common-guid.c',
'fu-chunk.c',
'fu-device.c',
'fu-device-locker.c',
@ -53,6 +54,7 @@ libfwupdprivate = static_library(
sqlite,
libarchive,
valgrind,
uuid,
],
c_args : [
'-DFU_OFFLINE_DESTDIR=""',
@ -108,6 +110,7 @@ fwupdtool = executable(
'fu-chunk.c',
'fu-common.c',
'fu-common-cab.c',
'fu-common-guid.c',
'fu-config.c',
'fu-keyring.c',
'fu-keyring-result.c',
@ -145,6 +148,7 @@ fwupdtool = executable(
sqlite,
valgrind,
libarchive,
uuid,
],
link_with : [
fwupd,
@ -184,6 +188,7 @@ executable(
'fu-chunk.c',
'fu-common.c',
'fu-common-cab.c',
'fu-common-guid.c',
'fu-config.c',
'fu-keyring.c',
'fu-keyring-result.c',
@ -223,6 +228,7 @@ executable(
sqlite,
valgrind,
libarchive,
uuid,
],
link_with : fwupd,
c_args : [
@ -251,6 +257,7 @@ if get_option('tests')
'fu-chunk.c',
'fu-common.c',
'fu-common-cab.c',
'fu-common-guid.c',
'fu-config.c',
'fu-engine.c',
'fu-keyring.c',
@ -289,6 +296,7 @@ if get_option('tests')
sqlite,
valgrind,
libarchive,
uuid,
],
link_with : [
fwupd,
@ -312,6 +320,8 @@ if get_option('introspection')
'fu-chunk.c',
'fu-chunk.h',
'fu-common.c',
'fu-common-guid.c',
'fu-common-guid.h',
'fu-common.h',
'fu-device.c',
'fu-device.h',