diff --git a/src/fu-install-task.c b/src/fu-install-task.c index 1ef286b58..5e44db5bd 100644 --- a/src/fu-install-task.c +++ b/src/fu-install-task.c @@ -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 && diff --git a/src/fu-self-test.c b/src/fu-self-test.c index 3b6e2a310..8553487f0 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -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 = + "" + " " + " 12345678-1234-1234-1234-123456789012" + " " + " " + " " + " " + " " + " " + ""; + + /* 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);