CLEANUP_ARRAY(elements, n_elements, sd_json_variant_unref_many);
for (;;) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *key = NULL;
const char *contents;
char type;
if (r < 0)
return r;
- r = json_transform_one(m, elements + n_elements);
+ r = json_transform_one(m, &key);
if (r < 0)
return r;
- n_elements++;
+ /* JSON only supports string keys in objects, but D-Bus specification is a bit more lenient
+ * and allows dict entries to have any basic type as key. Let's stringify allowed non-string
+ * keys so that we can represent them as JSON objects. */
+ if (!sd_json_variant_is_string(key)) {
+ _cleanup_free_ char *s = NULL;
+
+ if (!IN_SET(sd_json_variant_type(key),
+ SD_JSON_VARIANT_BOOLEAN,
+ SD_JSON_VARIANT_INTEGER,
+ SD_JSON_VARIANT_REAL,
+ SD_JSON_VARIANT_UNSIGNED))
+ return -EINVAL;
+
+ r = sd_json_variant_format(key, /* flags= */ 0, &s);
+ if (r < 0)
+ return r;
+
+ key = sd_json_variant_unref(key);
+
+ r = sd_json_variant_new_string(&key, s);
+ if (r < 0)
+ return r;
+ }
+
+ elements[n_elements++] = TAKE_PTR(key);
r = json_transform_one(m, elements + n_elements);
if (r < 0)
busctl call -j \
org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.DBus.Properties \
GetAll s "org.freedesktop.systemd1.Manager" | jq -c
+# Do the same with D-Bus' org.freedesktop.DBus.Debug.Stats interface which also provides some
+# complex signatures that caused issues during the JSON conversion in the past
+# See: https://github.com/systemd/systemd/issues/32904
+busctl call --json=pretty \
+ org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Debug.Stats \
+ GetStats | jq -c
busctl call --verbose --timeout=60 --expect-reply=yes \
org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager \
ListUnitsByPatterns asas 1 "active" 2 "systemd-*.socket" "*.mount"