The key_store_add_from_selector() function parses the argument of the
"--key" option in C-language tools:
OPTION_key [options/options.h]
key_store_add_from_selector() [options/keys.c]
key_store_import_key() [options/keys.c]
The function currently (a) uses a horrible "goto", (b) is not flexible
enough for selector types that do not take precisely 1 type-specific
parameter. Rewrite the function with more informative error messages and
an easier to follow structure, plus make the type-specific parameter count
a function of the type.
Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=1809453
Signed-off-by: Laszlo Ersek <lersek(a)redhat.com>
Reviewed-by: Richard W.M. Jones <rjones(a)redhat.com>
---
Notes:
v2:
- NULL-init the "fields" variable in key_store_add_from_selector(), for
more obvious CLEANUP_FREE_STRING_LIST hygiene [Rich]
- pick up Rich's R-b
options/keys.c | 46 ++++++++++----------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/options/keys.c b/options/keys.c
index 7729fe79c99b..37e1648fc969 100644
--- a/options/keys.c
+++ b/options/keys.c
@@ -210,48 +210,50 @@ free_keys (struct matching_key *keys, size_t nr_matches)
}
struct key_store *
key_store_add_from_selector (struct key_store *ks, const char *selector)
{
- CLEANUP_FREE_STRING_LIST char **fields =
- guestfs_int_split_string (':', selector);
+ CLEANUP_FREE_STRING_LIST char **fields = NULL;
+ size_t field_count;
struct key_store_key key;
+ fields = guestfs_int_split_string (':', selector);
if (!fields)
error (EXIT_FAILURE, errno, "guestfs_int_split_string");
+ field_count = guestfs_int_count_strings (fields);
- if (guestfs_int_count_strings (fields) != 3) {
- invalid_selector:
- error (EXIT_FAILURE, 0, "invalid selector for --key: %s", selector);
- }
-
- /* 1: device */
+ /* field#0: ID */
+ if (field_count < 1)
+ error (EXIT_FAILURE, 0, _("selector '%s': missing ID"), selector);
key.id = strdup (fields[0]);
if (!key.id)
error (EXIT_FAILURE, errno, "strdup");
- /* 2: key type */
- if (STREQ (fields[1], "key"))
+ /* field#1...: TYPE, and TYPE-specific properties */
+ if (field_count < 2)
+ error (EXIT_FAILURE, 0, _("selector '%s': missing TYPE"),
selector);
+
+ if (STREQ (fields[1], "key")) {
key.type = key_string;
- else if (STREQ (fields[1], "file"))
- key.type = key_file;
- else
- goto invalid_selector;
-
- /* 3: actual key */
- switch (key.type) {
- case key_string:
+ if (field_count != 3)
+ error (EXIT_FAILURE, 0,
+ _("selector '%s': missing KEY_STRING, or too many
fields"),
+ selector);
key.string.s = strdup (fields[2]);
if (!key.string.s)
error (EXIT_FAILURE, errno, "strdup");
- break;
- case key_file:
+ } else if (STREQ (fields[1], "file")) {
+ key.type = key_file;
+ if (field_count != 3)
+ error (EXIT_FAILURE, 0,
+ _("selector '%s': missing FILENAME, or too many fields"),
+ selector);
key.file.name = strdup (fields[2]);
if (!key.file.name)
error (EXIT_FAILURE, errno, "strdup");
- break;
- }
+ } else
+ error (EXIT_FAILURE, 0, _("selector '%s': invalid TYPE"),
selector);
return key_store_import_key (ks, &key);
}
struct key_store *
--
2.19.1.3.g30247aa5d201