[Libguestfs] [libguestfs-common PATCH 09/12] options: generalize "--key" selector parsing for C-language utilities

Laszlo Ersek lersek at redhat.com
Tue Jun 28 11:49:12 UTC 2022


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 at redhat.com>
---
 options/keys.c | 46 ++++++++++----------
 1 file changed, 24 insertions(+), 22 deletions(-)

diff --git a/options/keys.c b/options/keys.c
index 7729fe79c99b..a6ef2d78b589 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;
+  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




More information about the Libguestfs mailing list