mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 13:02:18 +00:00
Guess the version format when it is not provided
The most important change here is that versions without dots (not a 'semver') are treated as 'PLAIN' rather than 'UNKNOWN'.
This commit is contained in:
parent
69fca1d754
commit
ac458d3436
@ -332,7 +332,7 @@ fu_dell_dock_ec_get_dock_info (FuDevice *device,
|
||||
device_entry[i].version.version_8[2],
|
||||
device_entry[i].version.version_8[3]);
|
||||
g_debug ("\tParsed version %s", self->ec_version);
|
||||
fu_device_set_version (self, self->ec_version);
|
||||
fu_device_set_version (FU_DEVICE (self), self->ec_version);
|
||||
|
||||
} else if (map->device_type == FU_DELL_DOCK_DEVICETYPE_MST) {
|
||||
self->raw_versions->mst_version = device_entry[i].version.version_32;
|
||||
|
@ -202,6 +202,17 @@ fu_common_vercmp_chunk (const gchar *str1, const gchar *str2)
|
||||
return fu_common_vercmp_char (str1[i], str2[i]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_g_ascii_is_digits (const gchar *str)
|
||||
{
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
for (gsize i = 0; str[i] != '\0'; i++) {
|
||||
if (!g_ascii_isdigit (str[i]))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_version_parse:
|
||||
* @version: A version number
|
||||
@ -228,7 +239,6 @@ fu_common_version_parse (const gchar *version)
|
||||
gchar *endptr = NULL;
|
||||
guint64 tmp;
|
||||
guint base;
|
||||
guint i;
|
||||
|
||||
/* already dotted decimal */
|
||||
if (g_strstr_len (version, -1, ".") != NULL)
|
||||
@ -245,10 +255,8 @@ fu_common_version_parse (const gchar *version)
|
||||
base = 16;
|
||||
} else {
|
||||
/* for non-numeric content, just return the string */
|
||||
for (i = 0; version[i] != '\0'; i++) {
|
||||
if (!g_ascii_isdigit (version[i]))
|
||||
return g_strdup (version);
|
||||
}
|
||||
if (!_g_ascii_is_digits (version))
|
||||
return g_strdup (version);
|
||||
base = 10;
|
||||
}
|
||||
|
||||
@ -261,6 +269,56 @@ fu_common_version_parse (const gchar *version)
|
||||
return fu_common_version_from_uint32 ((guint32) tmp, FU_VERSION_FORMAT_TRIPLET);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_version_guess_format:
|
||||
* @version: A version number, e.g. "1.2.3"
|
||||
*
|
||||
* Guesses the version format from the version number. This is only a heuristic
|
||||
* and plugins and components should explicitly set the version format whenever
|
||||
* possible.
|
||||
*
|
||||
* If the version format cannot be guessed with any degree of accuracy, the
|
||||
* %FU_VERSION_FORMAT_UNKNOWN constant is returned.
|
||||
*
|
||||
* Returns: A #FuVersionFormat, e.g. %FU_VERSION_FORMAT_QUAD
|
||||
*
|
||||
* Since: 1.2.0
|
||||
*/
|
||||
FuVersionFormat
|
||||
fu_common_version_guess_format (const gchar *version)
|
||||
{
|
||||
guint sz;
|
||||
g_auto(GStrv) split = NULL;
|
||||
|
||||
/* nothing to use */
|
||||
if (version == NULL || version[0] == '\0')
|
||||
return FU_VERSION_FORMAT_UNKNOWN;
|
||||
|
||||
/* no dots, assume just text */
|
||||
split = g_strsplit (version, ".", -1);
|
||||
sz = g_strv_length (split);
|
||||
if (sz == 1)
|
||||
return FU_VERSION_FORMAT_PLAIN;
|
||||
|
||||
/* check for only-digit semver version */
|
||||
for (guint i = 0; split[i] != NULL; i++) {
|
||||
/* check sections are plain numbers */
|
||||
if (!_g_ascii_is_digits (split[i]))
|
||||
return FU_VERSION_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/* the most common formats */
|
||||
if (sz == 2)
|
||||
return FU_VERSION_FORMAT_PAIR;
|
||||
if (sz == 3)
|
||||
return FU_VERSION_FORMAT_TRIPLET;
|
||||
if (sz == 4)
|
||||
return FU_VERSION_FORMAT_QUAD;
|
||||
|
||||
/* unknown! */
|
||||
return FU_VERSION_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_vercmp:
|
||||
* @version_a: the release version, e.g. 1.2.3
|
||||
|
@ -45,5 +45,6 @@ gchar *fu_common_version_from_uint32 (guint32 val,
|
||||
gchar *fu_common_version_from_uint16 (guint16 val,
|
||||
FuVersionFormat flags);
|
||||
gchar *fu_common_version_parse (const gchar *version);
|
||||
FuVersionFormat fu_common_version_guess_format (const gchar *version);
|
||||
|
||||
#endif /* __FU_COMMON_VERSION_H__ */
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-common-guid.h"
|
||||
#include "fu-common-version.h"
|
||||
#include "fu-device-private.h"
|
||||
#include "fu-mutex.h"
|
||||
|
||||
@ -1046,6 +1047,29 @@ fu_device_set_id (FuDevice *self, const gchar *id)
|
||||
fwupd_device_set_id (FWUPD_DEVICE (self), id_hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_version:
|
||||
* @self: A #FuDevice
|
||||
* @version: a string, e.g. `1.2.3`
|
||||
*
|
||||
* Sets the device version, autodetecting the version format if required.
|
||||
*
|
||||
* Since: 1.2.1
|
||||
**/
|
||||
void
|
||||
fu_device_set_version (FuDevice *self, const gchar *version)
|
||||
{
|
||||
FuDevicePrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (FU_IS_DEVICE (self));
|
||||
g_return_if_fail (version != NULL);
|
||||
|
||||
/* try to autodetect the version-format */
|
||||
if (priv->version_format == FU_VERSION_FORMAT_UNKNOWN)
|
||||
priv->version_format = fu_common_version_guess_format (version);
|
||||
fwupd_device_set_version (FWUPD_DEVICE (self), version);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_ensure_id:
|
||||
* @self: A #FuDevice
|
||||
|
@ -94,7 +94,6 @@ FuDevice *fu_device_new (void);
|
||||
#define fu_device_set_update_state(d,v) fwupd_device_set_update_state(FWUPD_DEVICE(d),v)
|
||||
#define fu_device_set_vendor(d,v) fwupd_device_set_vendor(FWUPD_DEVICE(d),v)
|
||||
#define fu_device_set_vendor_id(d,v) fwupd_device_set_vendor_id(FWUPD_DEVICE(d),v)
|
||||
#define fu_device_set_version(d,v) fwupd_device_set_version(FWUPD_DEVICE(d),v)
|
||||
#define fu_device_set_version_lowest(d,v) fwupd_device_set_version_lowest(FWUPD_DEVICE(d),v)
|
||||
#define fu_device_set_version_bootloader(d,v) fwupd_device_set_version_bootloader(FWUPD_DEVICE(d),v)
|
||||
#define fu_device_set_flashes_left(d,v) fwupd_device_set_flashes_left(FWUPD_DEVICE(d),v)
|
||||
@ -158,6 +157,8 @@ void fu_device_set_metadata_integer (FuDevice *self,
|
||||
guint value);
|
||||
void fu_device_set_id (FuDevice *self,
|
||||
const gchar *id);
|
||||
void fu_device_set_version (FuDevice *self,
|
||||
const gchar *version);
|
||||
const gchar *fu_device_get_physical_id (FuDevice *self);
|
||||
void fu_device_set_physical_id (FuDevice *self,
|
||||
const gchar *physical_id);
|
||||
|
@ -52,6 +52,20 @@ fu_self_test_mkroot (void)
|
||||
g_assert_cmpint (g_mkdir_with_parents ("/tmp/fwupd-self-test/var/lib/fwupd", 0755), ==, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_common_version_guess_format_func (void)
|
||||
{
|
||||
g_assert_cmpint (fu_common_version_guess_format (NULL), ==, FU_VERSION_FORMAT_UNKNOWN);
|
||||
g_assert_cmpint (fu_common_version_guess_format (""), ==, FU_VERSION_FORMAT_UNKNOWN);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1234ac"), ==, FU_VERSION_FORMAT_PLAIN);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1.2"), ==, FU_VERSION_FORMAT_PAIR);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1.2.3"), ==, FU_VERSION_FORMAT_TRIPLET);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1.2.3.4"), ==, FU_VERSION_FORMAT_QUAD);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1.2.3.4.5"), ==, FU_VERSION_FORMAT_UNKNOWN);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1a.2b.3"), ==, FU_VERSION_FORMAT_UNKNOWN);
|
||||
g_assert_cmpint (fu_common_version_guess_format ("1"), ==, FU_VERSION_FORMAT_PLAIN);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_requirements_missing_func (void)
|
||||
{
|
||||
@ -857,7 +871,8 @@ fu_engine_history_func (void)
|
||||
" [Release]\n"
|
||||
" Version: 1.2.3\n"
|
||||
" Checksum: SHA1(%s)\n"
|
||||
" TrustFlags: none\n",
|
||||
" TrustFlags: none\n"
|
||||
" VersionFormat: triplet\n",
|
||||
checksum);
|
||||
ret = fu_test_compare_lines (device_str, device_str_expected, &error);
|
||||
g_assert_no_error (error);
|
||||
@ -986,7 +1001,8 @@ fu_engine_history_error_func (void)
|
||||
" [Release]\n"
|
||||
" Version: 1.2.3\n"
|
||||
" Checksum: SHA1(%s)\n"
|
||||
" TrustFlags: none\n",
|
||||
" TrustFlags: none\n"
|
||||
" VersionFormat: triplet\n",
|
||||
checksum);
|
||||
ret = fu_test_compare_lines (device_str, device_str_expected, &error);
|
||||
g_assert_no_error (error);
|
||||
@ -3214,6 +3230,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{version-guess-format}", fu_common_version_guess_format_func);
|
||||
g_test_add_func ("/fwupd/common{guid}", fu_common_guid_func);
|
||||
g_test_add_func ("/fwupd/common{version}", fu_common_version_func);
|
||||
g_test_add_func ("/fwupd/common{vercmp}", fu_common_vercmp_func);
|
||||
|
Loading…
Reference in New Issue
Block a user