Add fu_archive_firmware_get_image_fnmatch() for future use

It's useful to get images from archives by a specific filename extension.
This commit is contained in:
Richard Hughes 2022-12-16 16:46:04 +00:00
parent 08e3eaafe0
commit 069fa56f1a
7 changed files with 110 additions and 0 deletions

View File

@ -459,6 +459,7 @@ done
%{_datadir}/installed-tests/fwupd/*.test
%{_datadir}/installed-tests/fwupd/*.cab
%{_datadir}/installed-tests/fwupd/*.sh
%{_datadir}/installed-tests/fwupd/*.zip
%if 0%{?have_uefi}
%{_datadir}/installed-tests/fwupd/efi
%endif

View File

@ -12,6 +12,7 @@
#include "fu-archive-firmware.h"
#include "fu-archive.h"
#include "fu-common.h"
#include "fu-path.h"
/**
* FuArchiveFirmware:
@ -142,6 +143,55 @@ fu_archive_firmware_set_compression(FuArchiveFirmware *self, FuArchiveCompressio
priv->compression = compression;
}
/**
* fu_archive_firmware_get_image_fnmatch:
* @self: a #FuPlugin
* @pattern: (not nullable) a glob pattern, e.g. `*foo*`
* @error: (nullable): optional return location for an error
*
* Gets a single firmware image using the image ID pattern. It is also an error for multiple images
* to match.
*
* Returns: (transfer full): a #FuFirmware, or %NULL if the image is not found
*
* Since: 1.8.9
**/
FuFirmware *
fu_archive_firmware_get_image_fnmatch(FuArchiveFirmware *self, const gchar *pattern, GError **error)
{
g_autoptr(FuFirmware) img_match = NULL;
g_autoptr(GPtrArray) imgs = fu_firmware_get_images(FU_FIRMWARE(self));
g_return_val_if_fail(FU_IS_ARCHIVE_FIRMWARE(self), NULL);
g_return_val_if_fail(pattern != NULL, NULL);
g_return_val_if_fail(error == NULL || *error == NULL, NULL);
for (guint i = 0; i < imgs->len; i++) {
FuFirmware *img = g_ptr_array_index(imgs, i);
const gchar *fn = fu_firmware_get_id(img);
if (!fu_path_fnmatch(pattern, fn))
continue;
if (img_match != NULL) {
g_set_error(error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
"multiple images matched %s",
pattern);
return NULL;
}
img_match = g_object_ref(img);
}
if (img_match == NULL) {
g_set_error(error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"no image matched %s",
pattern);
return NULL;
}
return g_steal_pointer(&img_match);
}
static GBytes *
fu_archive_firmware_write(FuFirmware *firmware, GError **error)
{

View File

@ -28,3 +28,7 @@ FuArchiveCompression
fu_archive_firmware_get_compression(FuArchiveFirmware *self);
void
fu_archive_firmware_set_compression(FuArchiveFirmware *self, FuArchiveCompression compression);
FuFirmware *
fu_archive_firmware_get_image_fnmatch(FuArchiveFirmware *self,
const gchar *pattern,
GError **error);

View File

@ -2510,6 +2510,45 @@ fu_firmware_new_from_gtypes_func(void)
g_assert_null(firmware3);
}
static void
fu_firmware_archive_func(void)
{
gboolean ret;
g_autofree gchar *fn = NULL;
g_autoptr(FuFirmware) firmware = fu_archive_firmware_new();
g_autoptr(FuFirmware) img_asc = NULL;
g_autoptr(FuFirmware) img_bin = NULL;
g_autoptr(FuFirmware) img_both = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GFile) file = NULL;
fn = g_test_build_filename(G_TEST_BUILT, "tests", "firmware.zip", NULL);
file = g_file_new_for_path(fn);
ret = fu_firmware_parse_file(firmware, file, FWUPD_INSTALL_FLAG_NONE, &error);
g_assert_no_error(error);
g_assert_true(ret);
g_assert_cmpint(fu_archive_firmware_get_format(FU_ARCHIVE_FIRMWARE(firmware)),
==,
FU_ARCHIVE_FORMAT_UNKNOWN);
g_assert_cmpint(fu_archive_firmware_get_compression(FU_ARCHIVE_FIRMWARE(firmware)),
==,
FU_ARCHIVE_COMPRESSION_UNKNOWN);
img_bin =
fu_archive_firmware_get_image_fnmatch(FU_ARCHIVE_FIRMWARE(firmware), "*.bin", &error);
g_assert_no_error(error);
g_assert_nonnull(img_bin);
img_asc = fu_archive_firmware_get_image_fnmatch(FU_ARCHIVE_FIRMWARE(firmware),
"*.bin.asc",
&error);
g_assert_no_error(error);
g_assert_nonnull(img_bin);
img_both =
fu_archive_firmware_get_image_fnmatch(FU_ARCHIVE_FIRMWARE(firmware), "*.bin*", &error);
g_assert_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_null(img_both);
}
static void
fu_firmware_linear_func(void)
{
@ -3770,6 +3809,7 @@ main(int argc, char **argv)
g_test_add_func("/fwupd/smbios{class}", fu_smbios_class_func);
g_test_add_func("/fwupd/firmware", fu_firmware_func);
g_test_add_func("/fwupd/firmware{common}", fu_firmware_common_func);
g_test_add_func("/fwupd/firmware{archive}", fu_firmware_archive_func);
g_test_add_func("/fwupd/firmware{linear}", fu_firmware_linear_func);
g_test_add_func("/fwupd/firmware{dedupe}", fu_firmware_dedupe_func);
g_test_add_func("/fwupd/firmware{build}", fu_firmware_build_func);

View File

@ -1143,6 +1143,7 @@ LIBFWUPDPLUGIN_1.8.7 {
LIBFWUPDPLUGIN_1.8.9 {
global:
fu_archive_firmware_get_image_fnmatch;
fu_byte_array_to_string;
fu_version_from_uint24;
local: *;

View File

@ -340,6 +340,7 @@ if get_option('tests')
env.set('G_TEST_BUILDDIR', meson.current_build_dir())
e = executable(
'fwupdplugin-self-test',
installed_firmware_zip,
sources: [
'fu-self-test.c'
],

View File

@ -1,2 +1,15 @@
subdir('colorhug')
subdir('efi')
installed_firmware_zip = custom_target('installed-firmware-zip',
input: [
'colorhug/firmware.bin',
'colorhug/firmware.bin.asc',
],
output: 'firmware.zip',
command: [
python3, '-m', 'zipfile', '-c', '@OUTPUT@', '@INPUT@',
],
install: true,
install_dir: installed_test_datadir,
)