diff options
author | Ted Gould <ted@gould.cx> | 2011-03-02 09:35:04 -0600 |
---|---|---|
committer | Ted Gould <ted@gould.cx> | 2011-03-02 09:35:04 -0600 |
commit | 05298620b764d60b942567d09b970342924099f9 (patch) | |
tree | b262309d600acb73e4024285da6e756eba2460f7 | |
parent | 11d5033383efefb81d068acad6b1661654fa1194 (diff) | |
parent | 0e6db378e81e24f2ee2ff4498ff40dc60d1915bc (diff) | |
download | libdbusmenu-05298620b764d60b942567d09b970342924099f9.tar.gz libdbusmenu-05298620b764d60b942567d09b970342924099f9.tar.bz2 libdbusmenu-05298620b764d60b942567d09b970342924099f9.zip |
Handle the case where the passed in property name could be from the hashtable.
-rw-r--r-- | libdbusmenu-glib/client.c | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 21 |
2 files changed, 20 insertions, 3 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 8424d6f..83ca056 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1168,7 +1168,7 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian gchar * property; while (g_variant_iter_next(&properties, "s", &property)) { - g_debug("Removing property '%s' on %d", property, id); + /* g_debug("Removing property '%s' on %d", property, id); */ dbusmenu_menuitem_property_remove(menuitem, property); } } diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c index 855f4ee..f7867e4 100644 --- a/libdbusmenu-glib/menuitem.c +++ b/libdbusmenu-glib/menuitem.c @@ -1146,6 +1146,7 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE); g_return_val_if_fail(property != NULL, FALSE); + g_return_val_if_fail(g_utf8_validate(property, -1, NULL), FALSE); DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi); GVariant * default_value = NULL; @@ -1181,6 +1182,7 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro gboolean replaced = FALSE; + gboolean remove = FALSE; gpointer currentval = g_hash_table_lookup(priv->properties, property); if (value != NULL) { @@ -1195,10 +1197,21 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro gchar * lprop = g_strdup(property); g_variant_ref_sink(value); - g_hash_table_replace(priv->properties, lprop, value); + /* Really important that this is _insert as that means the value + that we just created in the _strdup is free'd and not the one + currently in the hashtable. That could be the same as the one + being passed in and then the signal emit would be done with a + bad value */ + g_hash_table_insert(priv->properties, lprop, value); } else { if (currentval != NULL) { - g_hash_table_remove(priv->properties, property); + /* So the question you should be asking if you're paying attention + is "Why not just do the remove here?" It's a good question with + an interesting answer. Bascially it's the same reason as above, + in a couple cases the passed in properties is the value in the hash + table so we can avoid strdup'ing it by removing it (and thus free'ing + it) after the signal emition */ + remove = TRUE; replaced = TRUE; } } @@ -1219,6 +1232,10 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, property, signalval, TRUE); } + if (remove) { + g_hash_table_remove(priv->properties, property); + } + return TRUE; } |