aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2020-04-15 09:49:26 +0200
committerMarkus Armbruster <armbru@redhat.com>2020-04-29 08:01:52 +0200
commit80c710cb06ff40b45de033e4352528b3adcd2de9 (patch)
tree75705e97e3babe95842ebeb51818a4f6fdc5d6f1
parent6d2b5cbafb8fb4bb3563cbf698b3a0903a993d7a (diff)
qemu-img: Move is_valid_option_list() to qemu-img.c and rewrite
is_valid_option_list()'s purpose is ensuring qemu-img.c's can safely join multiple parameter strings separated by ',' like this: g_strdup_printf("%s,%s", params1, params2); How it does that is anything but obvious. A close reading of the code reveals that it fails exactly when its argument starts with ',' or ends with an odd number of ','. Makes sense, actually, because when the argument starts with ',', a separating ',' preceding it would get escaped, and when it ends with an odd number of ',', a separating ',' following it would get escaped. Move it to qemu-img.c and rewrite it the obvious way. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20200415074927.19897-9-armbru@redhat.com>
-rw-r--r--include/qemu/option.h1
-rw-r--r--qemu-img.c26
-rw-r--r--util/qemu-option.c22
3 files changed, 26 insertions, 23 deletions
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 844587cab3..eb4097889d 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -33,7 +33,6 @@ const char *get_opt_value(const char *p, char **value);
void parse_option_size(const char *name, const char *value,
uint64_t *ret, Error **errp);
bool has_help_option(const char *param);
-bool is_valid_option_list(const char *param);
enum QemuOptType {
QEMU_OPT_STRING = 0, /* no parsing (use string as-is) */
diff --git a/qemu-img.c b/qemu-img.c
index d36b21b758..cc51db7ed4 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -223,6 +223,32 @@ static bool qemu_img_object_print_help(const char *type, QemuOpts *opts)
return true;
}
+/*
+ * Is @optarg safe for accumulate_options()?
+ * It is when multiple of them can be joined together separated by ','.
+ * To make that work, @optarg must not start with ',' (or else a
+ * separating ',' preceding it gets escaped), and it must not end with
+ * an odd number of ',' (or else a separating ',' following it gets
+ * escaped).
+ */
+static bool is_valid_option_list(const char *optarg)
+{
+ size_t len = strlen(optarg);
+ size_t i;
+
+ if (optarg[0] == ',') {
+ return false;
+ }
+
+ for (i = len; i > 0 && optarg[i - 1] == ','; i--) {
+ }
+ if ((len - i) % 2) {
+ return false;
+ }
+
+ return true;
+}
+
static int accumulate_options(char **options, char *optarg)
{
char *new_options;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 2d0d24ee27..9542988183 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -165,28 +165,6 @@ void parse_option_size(const char *name, const char *value,
*ret = size;
}
-bool is_valid_option_list(const char *p)
-{
- char *value = NULL;
- bool result = false;
-
- while (*p) {
- p = get_opt_value(p, &value);
- if ((*p && !*++p) ||
- (!*value || *value == ',')) {
- goto out;
- }
-
- g_free(value);
- value = NULL;
- }
-
- result = true;
-out:
- g_free(value);
- return result;
-}
-
static const char *opt_type_to_string(enum QemuOptType type)
{
switch (type) {