diff options
author | Thomas Haller <thaller@redhat.com> | 2017-11-21 13:35:46 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-11-21 13:48:49 +0100 |
commit | 3c8c63dcca9e6e8e8500d53589a5e8c56b78a4ff (patch) | |
tree | 47c24f1401be34f9ef168768434602f0d9f9eef7 | |
parent | 6b319cd0722085ef686b65b24b2c8de72c0fa25b (diff) | |
download | NetworkManager-3c8c63dcca9e6e8e8500d53589a5e8c56b78a4ff.tar.gz |
libnm: stable order in _nm_utils_strdict_to_dbus()
-rw-r--r-- | libnm-core/nm-utils.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index c3001ab5d1..ef72011393 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -490,17 +490,45 @@ _nm_utils_strdict_to_dbus (const GValue *prop_value) { GHashTable *hash; GHashTableIter iter; - gpointer key, value; + const char *key, *value; GVariantBuilder builder; + guint i, len; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + hash = g_value_get_boxed (prop_value); - if (hash) { - g_hash_table_iter_init (&iter, hash); - while (g_hash_table_iter_next (&iter, &key, &value)) - g_variant_builder_add (&builder, "{ss}", key, value); + if (!hash) + goto out; + len = g_hash_table_size (hash); + if (!len) + goto out; + + g_hash_table_iter_init (&iter, hash); + if (!g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) + nm_assert_not_reached (); + + if (len == 1) + g_variant_builder_add (&builder, "{ss}", key, value); + else { + gs_free NMUtilsNamedValue *idx = NULL; + + idx = g_new (NMUtilsNamedValue, len); + i = 0; + do { + idx[i].name = key; + idx[i].value_str = value; + i++; + } while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)); + nm_assert (i == len); + + g_qsort_with_data (idx, len, sizeof (idx[0]), + nm_utils_named_entry_cmp_with_data, NULL); + + for (i = 0; i < len; i++) + g_variant_builder_add (&builder, "{ss}", idx[i].name, idx[i].value_str); } +out: return g_variant_builder_end (&builder); } |