summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-11-21 13:35:46 +0100
committerThomas Haller <thaller@redhat.com>2017-11-21 13:48:49 +0100
commit3c8c63dcca9e6e8e8500d53589a5e8c56b78a4ff (patch)
tree47c24f1401be34f9ef168768434602f0d9f9eef7
parent6b319cd0722085ef686b65b24b2c8de72c0fa25b (diff)
downloadNetworkManager-3c8c63dcca9e6e8e8500d53589a5e8c56b78a4ff.tar.gz
libnm: stable order in _nm_utils_strdict_to_dbus()
-rw-r--r--libnm-core/nm-utils.c38
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);
}