qemu
1/*
2* Parsing KEY=VALUE,... strings
3*
4* Copyright (C) 2017 Red Hat Inc.
5*
6* Authors:
7* Markus Armbruster <armbru@redhat.com>,
8*
9* This work is licensed under the terms of the GNU GPL, version 2 or later.
10* See the COPYING file in the top-level directory.
11*/
12
13/*
14* KEY=VALUE,... syntax:
15*
16* key-vals = [ key-val { ',' key-val } [ ',' ] ]
17* key-val = key '=' val | help
18* key = key-fragment { '.' key-fragment }
19* key-fragment = qapi-name | index
20* qapi-name = '__' / [a-z0-9.-]+ / '_' / [A-Za-z][A-Za-z0-9_-]* /
21* index = / [0-9]+ /
22* val = { / [^,]+ / | ',,' }
23* help = 'help' | '?'
24*
25* Semantics defined by reduction to JSON:
26*
27* key-vals specifies a JSON object, i.e. a tree whose root is an
28* object, inner nodes other than the root are objects or arrays,
29* and leaves are strings.
30*
31* Each key-val = key-fragment '.' ... '=' val specifies a path from
32* root to a leaf (left of '='), and the leaf's value (right of
33* '=').
34*
35* A path from the root is defined recursively:
36* L '.' key-fragment is a child of the node denoted by path L
37* key-fragment is a child of the tree root
38* If key-fragment is numeric, the parent is an array and the child
39* is its key-fragment-th member, counting from zero.
40* Else, the parent is an object, and the child is its member named
41* key-fragment.
42*
43* This constrains inner nodes to be either array or object. The
44* constraints must be satisfiable. Counter-example: a.b=1,a=2 is
45* not, because root.a must be an object to satisfy a.b=1 and a
46* string to satisfy a=2.
47*
48* Array subscripts can occur in any order, but the set of
49* subscripts must not have gaps. For instance, a.1=v is not okay,
50* because root.a[0] is missing.
51*
52* If multiple key-val denote the same leaf, the last one determines
53* the value.
54*
55* Key-fragments must be valid QAPI names or consist only of decimal
56* digits.
57*
58* The length of any key-fragment must be between 1 and 127.
59*
60* If any key-val is help, the object is to be treated as a help
61* request.
62*
63* Design flaw: there is no way to denote an empty array or non-root
64* object. While interpreting "key absent" as empty seems natural
65* (removing a key-val from the input string removes the member when
66* there are more, so why not when it's the last), it doesn't work:
67* "key absent" already means "optional object/array absent", which
68* isn't the same as "empty object/array present".
69*
70* Design flaw: scalar values can only be strings; there is no way to
71* denote numbers, true, false or null. The special QObject input
72* visitor returned by qobject_input_visitor_new_keyval() mostly hides
73* this by automatically converting strings to the type the visitor
74* expects. Breaks down for type 'any', where the visitor's
75* expectation isn't clear. Code visiting 'any' needs to do the
76* conversion itself, but only when using this keyval visitor.
77* Awkward. Note that we carefully restrict alternate types to avoid
78* similar ambiguity.
79*
80* Alternative syntax for use with an implied key:
81*
82* key-vals = [ key-val-1st { ',' key-val } [ ',' ] ]
83* key-val-1st = val-no-key | key-val
84* val-no-key = / [^=,]+ / - help
85*
86* where val-no-key is syntactic sugar for implied-key=val-no-key.
87*
88* Note that you can't use the sugared form when the value contains
89* '=' or ','.
90*/
91
92#include "qemu/osdep.h"93#include "qapi/error.h"94#include "qapi/qmp/qdict.h"95#include "qapi/qmp/qlist.h"96#include "qapi/qmp/qstring.h"97#include "qemu/cutils.h"98#include "qemu/keyval.h"99#include "qemu/help_option.h"100
101/*
102* Convert @key to a list index.
103* Convert all leading decimal digits to a (non-negative) number,
104* capped at INT_MAX.
105* If @end is non-null, assign a pointer to the first character after
106* the number to *@end.
107* Else, fail if any characters follow.
108* On success, return the converted number.
109* On failure, return a negative value.
110* Note: since only digits are converted, no two keys can map to the
111* same number, except by overflow to INT_MAX.
112*/
113static int key_to_index(const char *key, const char **end)114{
115int ret;116unsigned long index;117
118if (*key < '0' || *key > '9') {119return -EINVAL;120}121ret = qemu_strtoul(key, end, 10, &index);122if (ret) {123return ret == -ERANGE ? INT_MAX : ret;124}125return index <= INT_MAX ? index : INT_MAX;126}
127
128/*
129* Ensure @cur maps @key_in_cur the right way.
130* If @value is null, it needs to map to a QDict, else to this
131* QString.
132* If @cur doesn't have @key_in_cur, put an empty QDict or @value,
133* respectively.
134* Else, if it needs to map to a QDict, and already does, do nothing.
135* Else, if it needs to map to this QString, and already maps to a
136* QString, replace it by @value.
137* Else, fail because we have conflicting needs on how to map
138* @key_in_cur.
139* In any case, take over the reference to @value, i.e. if the caller
140* wants to hold on to a reference, it needs to qobject_ref().
141* Use @key up to @key_cursor to identify the key in error messages.
142* On success, return the mapped value.
143* On failure, store an error through @errp and return NULL.
144*/
145static QObject *keyval_parse_put(QDict *cur,146const char *key_in_cur, QString *value,147const char *key, const char *key_cursor,148Error **errp)149{
150QObject *old, *new;151
152old = qdict_get(cur, key_in_cur);153if (old) {154if (qobject_type(old) != (value ? QTYPE_QSTRING : QTYPE_QDICT)) {155error_setg(errp, "Parameters '%.*s.*' used inconsistently",156(int)(key_cursor - key), key);157qobject_unref(value);158return NULL;159}160if (!value) {161return old; /* already QDict, do nothing */162}163new = QOBJECT(value); /* replacement */164} else {165new = value ? QOBJECT(value) : QOBJECT(qdict_new());166}167qdict_put_obj(cur, key_in_cur, new);168return new;169}
170
171/*
172* Parse one parameter from @params.
173*
174* If we're looking at KEY=VALUE, store result in @qdict.
175* The first fragment of KEY applies to @qdict. Subsequent fragments
176* apply to nested QDicts, which are created on demand. @implied_key
177* is as in keyval_parse().
178*
179* If we're looking at "help" or "?", set *help to true.
180*
181* On success, return a pointer to the next parameter, or else to '\0'.
182* On failure, return NULL.
183*/
184static const char *keyval_parse_one(QDict *qdict, const char *params,185const char *implied_key, bool *help,186Error **errp)187{
188const char *key, *key_end, *val_end, *s, *end;189size_t len;190char key_in_cur[128];191QDict *cur;192int ret;193QObject *next;194GString *val;195
196key = params;197val_end = NULL;198len = strcspn(params, "=,");199if (len && key[len] != '=') {200if (starts_with_help_option(key) == len) {201*help = true;202s = key + len;203if (*s == ',') {204s++;205}206return s;207}208if (implied_key) {209/* Desugar implied key */210key = implied_key;211val_end = params + len;212len = strlen(implied_key);213}214}215key_end = key + len;216
217/*218* Loop over key fragments: @s points to current fragment, it
219* applies to @cur. @key_in_cur[] holds the previous fragment.
220*/
221cur = qdict;222s = key;223for (;;) {224/* Want a key index (unless it's first) or a QAPI name */225if (s != key && key_to_index(s, &end) >= 0) {226len = end - s;227} else {228ret = parse_qapi_name(s, false);229len = ret < 0 ? 0 : ret;230}231assert(s + len <= key_end);232if (!len || (s + len < key_end && s[len] != '.')) {233assert(key != implied_key);234error_setg(errp, "Invalid parameter '%.*s'",235(int)(key_end - key), key);236return NULL;237}238if (len >= sizeof(key_in_cur)) {239assert(key != implied_key);240error_setg(errp, "Parameter%s '%.*s' is too long",241s != key || s + len != key_end ? " fragment" : "",242(int)len, s);243return NULL;244}245
246if (s != key) {247next = keyval_parse_put(cur, key_in_cur, NULL,248key, s - 1, errp);249if (!next) {250return NULL;251}252cur = qobject_to(QDict, next);253assert(cur);254}255
256memcpy(key_in_cur, s, len);257key_in_cur[len] = 0;258s += len;259
260if (*s != '.') {261break;262}263s++;264}265
266if (key == implied_key) {267assert(!*s);268val = g_string_new_len(params, val_end - params);269s = val_end;270if (*s == ',') {271s++;272}273} else {274if (*s != '=') {275error_setg(errp, "Expected '=' after parameter '%.*s'",276(int)(s - key), key);277return NULL;278}279s++;280
281val = g_string_new(NULL);282for (;;) {283if (!*s) {284break;285} else if (*s == ',') {286s++;287if (*s != ',') {288break;289}290}291g_string_append_c(val, *s++);292}293}294
295if (!keyval_parse_put(cur, key_in_cur, qstring_from_gstring(val),296key, key_end, errp)) {297return NULL;298}299return s;300}
301
302static char *reassemble_key(GSList *key)303{
304GString *s = g_string_new("");305GSList *p;306
307for (p = key; p; p = p->next) {308g_string_prepend_c(s, '.');309g_string_prepend(s, (char *)p->data);310}311
312return g_string_free(s, FALSE);313}
314
315/*
316* Recursive worker for keyval_merge.
317*
318* @str is the path that led to the * current dictionary (to be used for
319* error messages). It is modified internally but restored before the
320* function returns.
321*/
322static void keyval_do_merge(QDict *dest, const QDict *merged, GString *str, Error **errp)323{
324size_t save_len = str->len;325const QDictEntry *ent;326QObject *old_value;327
328for (ent = qdict_first(merged); ent; ent = qdict_next(merged, ent)) {329old_value = qdict_get(dest, ent->key);330if (old_value) {331if (qobject_type(old_value) != qobject_type(ent->value)) {332error_setg(errp, "Parameter '%s%s' used inconsistently",333str->str, ent->key);334return;335} else if (qobject_type(ent->value) == QTYPE_QDICT) {336/* Merge sub-dictionaries. */337g_string_append(str, ent->key);338g_string_append_c(str, '.');339keyval_do_merge(qobject_to(QDict, old_value),340qobject_to(QDict, ent->value),341str, errp);342g_string_truncate(str, save_len);343continue;344} else if (qobject_type(ent->value) == QTYPE_QLIST) {345/* Append to old list. */346QList *old = qobject_to(QList, old_value);347QList *new = qobject_to(QList, ent->value);348const QListEntry *item;349QLIST_FOREACH_ENTRY(new, item) {350qobject_ref(item->value);351qlist_append_obj(old, item->value);352}353continue;354} else {355assert(qobject_type(ent->value) == QTYPE_QSTRING);356}357}358
359qobject_ref(ent->value);360qdict_put_obj(dest, ent->key, ent->value);361}362}
363
364/* Merge the @merged dictionary into @dest.
365*
366* The dictionaries are expected to be returned by the keyval parser, and
367* therefore the only expected scalar type is the string. In case the same
368* path is present in both @dest and @merged, the semantics are as follows:
369*
370* - lists are concatenated
371*
372* - dictionaries are merged recursively
373*
374* - for scalar values, @merged wins
375*
376* In case an error is reported, @dest may already have been modified.
377*
378* This function can be used to implement semantics analogous to QemuOpts's
379* .merge_lists = true case, or to implement -set for options backed by QDicts.
380*
381* Note: while QemuOpts is commonly used so that repeated keys overwrite
382* ("last one wins"), it can also be used so that repeated keys build up
383* a list. keyval_merge() can only be used when the options' semantics are
384* the former, not the latter.
385*/
386void keyval_merge(QDict *dest, const QDict *merged, Error **errp)387{
388GString *str;389
390str = g_string_new("");391keyval_do_merge(dest, merged, str, errp);392g_string_free(str, TRUE);393}
394
395/*
396* Listify @cur recursively.
397* Replace QDicts whose keys are all valid list indexes by QLists.
398* @key_of_cur is the list of key fragments leading up to @cur.
399* On success, return either @cur or its replacement.
400* On failure, store an error through @errp and return NULL.
401*/
402static QObject *keyval_listify(QDict *cur, GSList *key_of_cur, Error **errp)403{
404GSList key_node;405bool has_index, has_member;406const QDictEntry *ent;407QDict *qdict;408QObject *val;409char *key;410size_t nelt;411QObject **elt;412int index, max_index, i;413QList *list;414
415key_node.next = key_of_cur;416
417/*418* Recursively listify @cur's members, and figure out whether @cur
419* itself is to be listified.
420*/
421has_index = false;422has_member = false;423for (ent = qdict_first(cur); ent; ent = qdict_next(cur, ent)) {424if (key_to_index(ent->key, NULL) >= 0) {425has_index = true;426} else {427has_member = true;428}429
430qdict = qobject_to(QDict, ent->value);431if (!qdict) {432continue;433}434
435key_node.data = ent->key;436val = keyval_listify(qdict, &key_node, errp);437if (!val) {438return NULL;439}440if (val != ent->value) {441qdict_put_obj(cur, ent->key, val);442}443}444
445if (has_index && has_member) {446key = reassemble_key(key_of_cur);447error_setg(errp, "Parameters '%s*' used inconsistently", key);448g_free(key);449return NULL;450}451if (!has_index) {452return QOBJECT(cur);453}454
455/* Copy @cur's values to @elt[] */456nelt = qdict_size(cur) + 1; /* one extra, for use as sentinel */457elt = g_new0(QObject *, nelt);458max_index = -1;459for (ent = qdict_first(cur); ent; ent = qdict_next(cur, ent)) {460index = key_to_index(ent->key, NULL);461assert(index >= 0);462if (index > max_index) {463max_index = index;464}465/*466* We iterate @nelt times. If we get one exceeding @nelt
467* here, we will put less than @nelt values into @elt[],
468* triggering the error in the next loop.
469*/
470if ((size_t)index >= nelt - 1) {471continue;472}473/* Even though dict keys are distinct, indexes need not be */474elt[index] = ent->value;475}476
477/*478* Make a list from @elt[], reporting the first missing element,
479* if any.
480* If we dropped an index >= nelt in the previous loop, this loop
481* will run into the sentinel and report index @nelt missing.
482*/
483list = qlist_new();484assert(!elt[nelt-1]); /* need the sentinel to be null */485for (i = 0; i < MIN(nelt, max_index + 1); i++) {486if (!elt[i]) {487key = reassemble_key(key_of_cur);488error_setg(errp, "Parameter '%s%d' missing", key, i);489g_free(key);490g_free(elt);491qobject_unref(list);492return NULL;493}494qobject_ref(elt[i]);495qlist_append_obj(list, elt[i]);496}497
498g_free(elt);499return QOBJECT(list);500}
501
502/*
503* Parse @params in QEMU's traditional KEY=VALUE,... syntax.
504*
505* If @implied_key, the first KEY= can be omitted. @implied_key is
506* implied then, and VALUE can't be empty or contain ',' or '='.
507*
508* A parameter "help" or "?" without a value isn't added to the
509* resulting dictionary, but instead is interpreted as help request.
510* All other options are parsed and returned normally so that context
511* specific help can be printed.
512*
513* If @p_help is not NULL, store whether help is requested there.
514* If @p_help is NULL and help is requested, fail.
515*
516* On success, return @dict, now filled with the parsed keys and values.
517*
518* On failure, store an error through @errp and return NULL. Any keys
519* and values parsed so far will be in @dict nevertheless.
520*/
521QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,522bool *p_help, Error **errp)523{
524QObject *listified;525const char *s;526bool help = false;527
528s = params;529while (*s) {530s = keyval_parse_one(qdict, s, implied_key, &help, errp);531if (!s) {532return NULL;533}534implied_key = NULL;535}536
537if (p_help) {538*p_help = help;539} else if (help) {540error_setg(errp, "Help is not available for this option");541return NULL;542}543
544listified = keyval_listify(qdict, NULL, errp);545if (!listified) {546return NULL;547}548assert(listified == QOBJECT(qdict));549return qdict;550}
551
552/*
553* Parse @params in QEMU's traditional KEY=VALUE,... syntax.
554*
555* If @implied_key, the first KEY= can be omitted. @implied_key is
556* implied then, and VALUE can't be empty or contain ',' or '='.
557*
558* A parameter "help" or "?" without a value isn't added to the
559* resulting dictionary, but instead is interpreted as help request.
560* All other options are parsed and returned normally so that context
561* specific help can be printed.
562*
563* If @p_help is not NULL, store whether help is requested there.
564* If @p_help is NULL and help is requested, fail.
565*
566* On success, return a dictionary of the parsed keys and values.
567* On failure, store an error through @errp and return NULL.
568*/
569QDict *keyval_parse(const char *params, const char *implied_key,570bool *p_help, Error **errp)571{
572QDict *qdict = qdict_new();573QDict *ret = keyval_parse_into(qdict, params, implied_key, p_help, errp);574
575if (!ret) {576qobject_unref(qdict);577}578return ret;579}
580