Require --force to install a release with a different version format

If the user is trying to install version '20190104' on something with the
existing version '1.2.3' then something has gone wrong. Ensure the device
release version format matches the release version format and fail to apply the
update if this is not true.

In the common case setting the version with fu_device_set_version('1.2.3')
would set the version format to TRIPLET, and setting <release version='1.2.3'>
so no action is required. In cases where the version format could be ambiguous
then the format should be set both in a quirk and also in the metainfo file.
This commit is contained in:
Richard Hughes 2019-04-08 11:31:21 +01:00
parent 0b3e9fdb96
commit ce3cea8cb4
2 changed files with 82 additions and 0 deletions

View File

@ -92,6 +92,20 @@ fu_install_task_get_is_downgrade (FuInstallTask *self)
return self->is_downgrade;
}
static FuVersionFormat
fu_install_task_guess_version_format (FuInstallTask *self, const gchar *version)
{
const gchar *tmp;
/* explicit set */
tmp = xb_node_query_text (self->component, "custom/value[@key='LVFS::VersionFormat']", NULL);
if (tmp != NULL)
return fu_common_version_format_from_string (tmp);
/* count section from dotted notation */
return fu_common_version_guess_format (version);
}
/**
* fu_install_task_check_requirements:
* @self: A #FuInstallTask
@ -109,6 +123,7 @@ fu_install_task_check_requirements (FuInstallTask *self,
FwupdInstallFlags flags,
GError **error)
{
FuVersionFormat fmt;
const gchar *version;
const gchar *version_release;
const gchar *version_lowest;
@ -217,6 +232,26 @@ fu_install_task_check_requirements (FuInstallTask *self,
return FALSE;
}
/* check the version formats match */
fmt = fu_install_task_guess_version_format (self, version_release);
if (fmt != fu_device_get_version_format (self->device)) {
FuVersionFormat fmt_dev = fu_device_get_version_format (self->device);
if (flags & FWUPD_INSTALL_FLAG_FORCE) {
g_warning ("ignoring version format difference %s:%s",
fu_common_version_format_to_string (fmt_dev),
fu_common_version_format_to_string (fmt));
} else {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"Firmware version formats were different, "
"device was '%s' and release is '%s'",
fu_common_version_format_to_string (fmt_dev),
fu_common_version_format_to_string (fmt));
return FALSE;
}
}
/* compare to the lowest supported version, if it exists */
version_lowest = fu_device_get_version_lowest (self->device);
if (version_lowest != NULL &&

View File

@ -433,6 +433,52 @@ fu_engine_requirements_device_func (void)
g_assert (ret);
}
static void
fu_engine_requirements_version_format_func (void)
{
gboolean ret;
g_autoptr(FuDevice) device = fu_device_new ();
g_autoptr(FuEngine) engine = fu_engine_new (FU_APP_FLAGS_NONE);
g_autoptr(FuInstallTask) task = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(XbNode) component = NULL;
g_autoptr(XbSilo) silo = NULL;
const gchar *xml =
"<component>"
" <provides>"
" <firmware type=\"flashed\">12345678-1234-1234-1234-123456789012</firmware>"
" </provides>"
" <releases>"
" <release version=\"1.2.4\">"
" <checksum type=\"sha1\" filename=\"bios.bin\" target=\"content\"/>"
" </release>"
" </releases>"
"</component>";
/* set up a dummy device */
fu_device_set_version (device, "1.2.3.4");
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012");
/* make the component require three things */
silo = xb_silo_new_from_xml (xml, &error);
g_assert_no_error (error);
g_assert_nonnull (silo);
component = xb_silo_query_first (silo, "component", &error);
g_assert_no_error (error);
g_assert_nonnull (component);
/* check this fails */
task = fu_install_task_new (device, component);
ret = fu_engine_check_requirements (engine, task,
FWUPD_INSTALL_FLAG_NONE,
&error);
g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
g_assert_nonnull (g_strstr_len (error->message, -1,
"Firmware version formats were different"));
g_assert (!ret);
}
static void
fu_engine_requirements_other_device_func (void)
{
@ -3664,6 +3710,7 @@ main (int argc, char **argv)
g_test_add_func ("/fwupd/engine{requirements-not-child-fail}", fu_engine_requirements_child_fail_func);
g_test_add_func ("/fwupd/engine{requirements-unsupported}", fu_engine_requirements_unsupported_func);
g_test_add_func ("/fwupd/engine{requirements-device}", fu_engine_requirements_device_func);
g_test_add_func ("/fwupd/engine{requirements-version-format}", fu_engine_requirements_version_format_func);
g_test_add_func ("/fwupd/engine{device-auto-parent}", fu_engine_device_parent_func);
g_test_add_func ("/fwupd/engine{device-priority}", fu_engine_device_priority_func);
g_test_add_func ("/fwupd/engine{install-duration}", fu_engine_install_duration_func);