From 070310a680b0ea16af98efb592a1f4771022e791 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 14 Dec 2017 18:03:04 +0100 Subject: [PATCH] virjson: Deflatten arrays generated by the json->commandline generator For the few instances where we'd generate an array in dotted syntax we should be able to parse it back. Add another step in deflattening of the dotted syntax which reconstructs the arrays so that the backing store parser can parse it. https://bugzilla.redhat.com/show_bug.cgi?id=1466177 Signed-off-by: Peter Krempa Reviewed-by: Michal Privoznik --- src/util/virjson.c | 61 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/util/virjson.c b/src/util/virjson.c index 65d6521789..be472d49e4 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -2131,6 +2131,58 @@ virJSONValueObjectDeflattenKeys(virJSONValuePtr json) } +/** + * virJSONValueObjectDeflattenArrays: + * + * Reconstruct JSON arrays from objects which only have sequential numeric + * keys starting from 0. + */ +static void +virJSONValueObjectDeflattenArrays(virJSONValuePtr json) +{ + g_autofree virJSONValuePtr *arraymembers = NULL; + virJSONObjectPtr obj; + size_t i; + + if (!json || + json->type != VIR_JSON_TYPE_OBJECT) + return; + + obj = &json->data.object; + + arraymembers = g_new0(virJSONValuePtr, obj->npairs); + + for (i = 0; i < obj->npairs; i++) + virJSONValueObjectDeflattenArrays(obj->pairs[i].value); + + for (i = 0; i < obj->npairs; i++) { + virJSONObjectPairPtr pair = obj->pairs + i; + unsigned int keynum; + + if (virStrToLong_uip(pair->key, NULL, 10, &keynum) < 0) + return; + + if (keynum >= obj->npairs) + return; + + if (arraymembers[keynum]) + return; + + arraymembers[keynum] = pair->value; + } + + for (i = 0; i < obj->npairs; i++) + g_free(obj->pairs[i].key); + + g_free(json->data.object.pairs); + + i = obj->npairs; + json->type = VIR_JSON_TYPE_ARRAY; + json->data.array.nvalues = i; + json->data.array.values = g_steal_pointer(&arraymembers); +} + + /** * virJSONValueObjectDeflatten: * @@ -2146,5 +2198,12 @@ virJSONValueObjectDeflattenKeys(virJSONValuePtr json) virJSONValuePtr virJSONValueObjectDeflatten(virJSONValuePtr json) { - return virJSONValueObjectDeflattenKeys(json); + virJSONValuePtr deflattened; + + if (!(deflattened = virJSONValueObjectDeflattenKeys(json))) + return NULL; + + virJSONValueObjectDeflattenArrays(deflattened); + + return deflattened; }