]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virjson: Deflatten arrays generated by the json->commandline generator
authorPeter Krempa <pkrempa@redhat.com>
Thu, 14 Dec 2017 17:03:04 +0000 (18:03 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 20 Mar 2020 08:47:16 +0000 (09:47 +0100)
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 <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/util/virjson.c

index 65d6521789fcee0d92e66e9122df724575e831b0..be472d49e442e9e5bb54fd5775325d6d87ea2507 100644 (file)
@@ -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;
 }