Merge lp:~chrisccoulson/libdbusmenu/lp722972-part-2 into lp:libdbusmenu/0.5

Proposed by Chris Coulson
Status: Merged
Approved by: Ted Gould
Approved revision: 269
Merged at revision: 269
Proposed branch: lp:~chrisccoulson/libdbusmenu/lp722972-part-2
Merge into: lp:libdbusmenu/0.5
Diff against target: 356 lines (+102/-39)
1 file modified
libdbusmenu-glib/client.c (+102/-39)
To merge this branch: bzr merge lp:~chrisccoulson/libdbusmenu/lp722972-part-2
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+53311@code.launchpad.net

Description of the change

The g_variant_get_* family of calls which return a GVariant actually return reference counted, non-floating variant. Ensure that we always keep pointers to these so that we can properly unref them.

The same also applies to g_variant_iter_next_value.

Also fix a couple of other minor leaks along the way. This fixes LP: #722972

To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

Wow, looks really good. Thanks!

  review approve
  merge approve

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libdbusmenu-glib/client.c'
--- libdbusmenu-glib/client.c 2011-03-10 16:27:52 +0000
+++ libdbusmenu-glib/client.c 2011-03-14 19:34:36 +0000
@@ -598,20 +598,27 @@
598 }598 }
599599
600 /* Callback all the folks we can find */600 /* Callback all the folks we can find */
601 GVariantIter * iter = g_variant_iter_new(g_variant_get_child_value(params, 0));601 GVariant * child = g_variant_get_child_value(params, 0);
602 GVariant * child;602 GVariantIter * iter = g_variant_iter_new(child);
603 g_variant_unref(child);
603 while ((child = g_variant_iter_next_value(iter)) != NULL) {604 while ((child = g_variant_iter_next_value(iter)) != NULL) {
604 if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) {605 if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) {
605 g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child));606 g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child));
607 g_variant_unref(child);
606 continue;608 continue;
607 }609 }
608610
609 gint id = g_variant_get_int32(g_variant_get_child_value(child, 0));611 GVariant * idv = g_variant_get_child_value(child, 0);
612 gint id = g_variant_get_int32(idv);
613 g_variant_unref(idv);
614
610 GVariant * properties = g_variant_get_child_value(child, 1);615 GVariant * properties = g_variant_get_child_value(child, 1);
611616
612 properties_listener_t * listener = find_listener(listeners, 0, id);617 properties_listener_t * listener = find_listener(listeners, 0, id);
613 if (listener == NULL) {618 if (listener == NULL) {
614 g_warning("Unable to find listener for ID %d", id);619 g_warning("Unable to find listener for ID %d", id);
620 g_variant_unref(properties);
621 g_variant_unref(child);
615 continue;622 continue;
616 }623 }
617624
@@ -621,6 +628,8 @@
621 } else {628 } else {
622 g_warning("Odd, we've already replied to the listener on ID %d", id);629 g_warning("Odd, we've already replied to the listener on ID %d", id);
623 }630 }
631 g_variant_unref(properties);
632 g_variant_unref(child);
624 }633 }
625 g_variant_iter_free(iter);634 g_variant_iter_free(iter);
626 g_variant_unref(params);635 g_variant_unref(params);
@@ -676,7 +685,9 @@
676 GVariant * variant_ids = g_variant_builder_end(&builder);685 GVariant * variant_ids = g_variant_builder_end(&builder);
677686
678 /* Build up a prop list to pass */687 /* Build up a prop list to pass */
679 g_variant_builder_init(&builder, g_variant_type_new("as"));688 GVariantType * type = g_variant_type_new("as");
689 g_variant_builder_init(&builder, type);
690 g_variant_type_free(type);
680 /* TODO: need to use delayed property list here */691 /* TODO: need to use delayed property list here */
681 GVariant * variant_props = g_variant_builder_end(&builder);692 GVariant * variant_props = g_variant_builder_end(&builder);
682693
@@ -1050,12 +1061,13 @@
1050 /* Check the text direction if available */1061 /* Check the text direction if available */
1051 GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "TextDirection");1062 GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "TextDirection");
1052 if (textdir != NULL) {1063 if (textdir != NULL) {
1053 GVariant * str = textdir;1064 if (g_variant_is_of_type(textdir, G_VARIANT_TYPE_VARIANT)) {
1054 if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {1065 GVariant * tmp = g_variant_get_variant(textdir);
1055 str = g_variant_get_variant(str);1066 g_variant_unref(textdir);
1067 textdir = tmp;
1056 }1068 }
10571069
1058 priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));1070 priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(textdir, NULL));
1059 g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_TEXT_DIRECTION);1071 g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_TEXT_DIRECTION);
10601072
1061 g_variant_unref(textdir);1073 g_variant_unref(textdir);
@@ -1063,13 +1075,14 @@
10631075
1064 /* Check the status if available */1076 /* Check the status if available */
1065 GVariant * status = g_dbus_proxy_get_cached_property(priv->menuproxy, "Status");1077 GVariant * status = g_dbus_proxy_get_cached_property(priv->menuproxy, "Status");
1066 if (textdir != NULL) {1078 if (status != NULL) {
1067 GVariant * str = status;1079 if (g_variant_is_of_type(status, G_VARIANT_TYPE_VARIANT)) {
1068 if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {1080 GVariant * tmp = g_variant_get_variant(status);
1069 str = g_variant_get_variant(str);1081 g_variant_unref(status);
1082 status = tmp;
1070 }1083 }
10711084
1072 priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL));1085 priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(status, NULL));
1073 g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_STATUS);1086 g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_STATUS);
10741087
1075 g_variant_unref(status);1088 g_variant_unref(status);
@@ -1142,20 +1155,22 @@
1142 g_variant_iter_init(&iters, properties);1155 g_variant_iter_init(&iters, properties);
1143 while (g_variant_iter_next(&iters, "{sv}", &key, &value)) {1156 while (g_variant_iter_next(&iters, "{sv}", &key, &value)) {
1144 if (g_strcmp0(key, "TextDirection") == 0) {1157 if (g_strcmp0(key, "TextDirection") == 0) {
1145 GVariant * str = value;1158 if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT)) {
1146 if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {1159 GVariant * tmp = g_variant_get_variant(value);
1147 str = g_variant_get_variant(str);1160 g_variant_unref(value);
1161 value = tmp;
1148 }1162 }
11491163
1150 priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));1164 priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(value, NULL));
1151 }1165 }
1152 if (g_strcmp0(key, "Status") == 0) {1166 if (g_strcmp0(key, "Status") == 0) {
1153 GVariant * str = value;1167 if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT)) {
1154 if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {1168 GVariant * tmp = g_variant_get_variant(value);
1155 str = g_variant_get_variant(str);1169 g_variant_unref(value);
1170 value = tmp;
1156 }1171 }
11571172
1158 priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL));1173 priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(value, NULL));
1159 }1174 }
1160 if (g_strcmp0(key, "IconThemePath") == 0) {1175 if (g_strcmp0(key, "IconThemePath") == 0) {
1161 if (priv->icon_dirs != NULL) {1176 if (priv->icon_dirs != NULL) {
@@ -1224,11 +1239,14 @@
1224 /* Remove before adding just incase there is a duplicate, against the1239 /* Remove before adding just incase there is a duplicate, against the
1225 rules, but we can handle it so let's do it. */1240 rules, but we can handle it so let's do it. */
1226 GVariantIter ritems;1241 GVariantIter ritems;
1227 g_variant_iter_init(&ritems, g_variant_get_child_value(params, 1));1242 GVariant * ritemsv = g_variant_get_child_value(params, 1);
1243 g_variant_iter_init(&ritems, ritemsv);
12281244
1229 GVariant * ritem;1245 GVariant * ritem;
1230 while ((ritem = g_variant_iter_next_value(&ritems)) != NULL) {1246 while ((ritem = g_variant_iter_next_value(&ritems)) != NULL) {
1231 gint id = g_variant_get_int32(g_variant_get_child_value(ritem, 0));1247 GVariant * idv = g_variant_get_child_value(ritem, 0);
1248 gint id = g_variant_get_int32(idv);
1249 g_variant_unref(idv);
1232 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);1250 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
12331251
1234 if (menuitem == NULL) {1252 if (menuitem == NULL) {
@@ -1236,7 +1254,8 @@
1236 }1254 }
12371255
1238 GVariantIter properties;1256 GVariantIter properties;
1239 g_variant_iter_init(&properties, g_variant_get_child_value(ritem, 1));1257 GVariant * propv = g_variant_get_child_value(ritem, 1);
1258 g_variant_iter_init(&properties, propv);
1240 gchar * property;1259 gchar * property;
12411260
1242 while (g_variant_iter_next(&properties, "s", &property)) {1261 while (g_variant_iter_next(&properties, "s", &property)) {
@@ -1245,16 +1264,23 @@
1245 g_free(property);1264 g_free(property);
1246 }1265 }
1247 g_variant_unref(ritem);1266 g_variant_unref(ritem);
1267 g_variant_unref(propv);
1248 }1268 }
1269 g_variant_unref(ritemsv);
12491270
1250 GVariantIter items;1271 GVariantIter items;
1251 g_variant_iter_init(&items, g_variant_get_child_value(params, 0));1272 GVariant * itemsv = g_variant_get_child_value(params, 0);
1273 g_variant_iter_init(&items, itemsv);
12521274
1253 GVariant * item;1275 GVariant * item;
1254 while ((item = g_variant_iter_next_value(&items)) != NULL) {1276 while ((item = g_variant_iter_next_value(&items)) != NULL) {
1255 gint id = g_variant_get_int32(g_variant_get_child_value(item, 0));1277 GVariant * idv = g_variant_get_child_value(item, 0);
1278 gint id = g_variant_get_int32(idv);
1279 g_variant_unref(idv);
1280
1256 GVariantIter properties;1281 GVariantIter properties;
1257 g_variant_iter_init(&properties, g_variant_get_child_value(item, 1));1282 GVariant * propv = g_variant_get_child_value(item, 1);
1283 g_variant_iter_init(&properties, propv);
1258 gchar * property;1284 gchar * property;
1259 GVariant * value;1285 GVariant * value;
12601286
@@ -1263,14 +1289,21 @@
1263 if (G_LIKELY(g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT))) {1289 if (G_LIKELY(g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT))) {
1264 /* Unboxing if needed */1290 /* Unboxing if needed */
1265 internalvalue = g_variant_get_variant(value);1291 internalvalue = g_variant_get_variant(value);
1292 g_variant_unref(value);
1266 }1293 }
1267 id_prop_update(proxy, id, property, internalvalue, client);1294 id_prop_update(proxy, id, property, internalvalue, client);
1295 g_variant_unref(internalvalue);
1268 }1296 }
1297 g_variant_unref(propv);
1298 g_variant_unref(item);
1269 }1299 }
1300 g_variant_unref(itemsv);
1270 } else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) {1301 } else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) {
1271 gint id; gchar * property; GVariant * value;1302 gint id; gchar * property; GVariant * value;
1272 g_variant_get(params, "(isv)", &id, &property, &value);1303 g_variant_get(params, "(isv)", &id, &property, &value);
1273 id_prop_update(proxy, id, property, value, client);1304 id_prop_update(proxy, id, property, value, client);
1305 g_free(property);
1306 g_variant_unref(value);
1274 } else if (g_strcmp0(signal, "ItemUpdated") == 0) {1307 } else if (g_strcmp0(signal, "ItemUpdated") == 0) {
1275 gint id;1308 gint id;
1276 g_variant_get(params, "(i)", &id);1309 g_variant_get(params, "(i)", &id);
@@ -1594,7 +1627,9 @@
1594 }1627 }
15951628
1596 /* First verify and figure out what we've got */1629 /* First verify and figure out what we've got */
1597 gint id = g_variant_get_int32(g_variant_get_child_value(layout, 0));1630 GVariant * idv = g_variant_get_child_value(layout, 0);
1631 gint id = g_variant_get_int32(idv);
1632 g_variant_unref(idv);
1598 if (id < 0) {1633 if (id < 0) {
1599 return NULL;1634 return NULL;
1600 }1635 }
@@ -1607,8 +1642,10 @@
16071642
1608 /* Some variables */1643 /* Some variables */
1609 GVariantIter children;1644 GVariantIter children;
1610 g_variant_iter_init(&children, g_variant_get_child_value(layout, 2));1645 GVariant * childrenv;
1611 GVariant * child;1646
1647 childrenv = g_variant_get_child_value(layout, 2);
1648 g_variant_iter_init(&children, childrenv);
16121649
1613 guint position = 0;1650 guint position = 0;
1614 GList * oldchildren = g_list_copy(dbusmenu_menuitem_get_children(item));1651 GList * oldchildren = g_list_copy(dbusmenu_menuitem_get_children(item));
@@ -1616,16 +1653,22 @@
16161653
1617 /* Go through all the XML Nodes and make sure that we have menuitems1654 /* Go through all the XML Nodes and make sure that we have menuitems
1618 to cover those XML nodes. */1655 to cover those XML nodes. */
1656 GVariant * child;
1619 while ((child = g_variant_iter_next_value(&children)) != NULL) {1657 while ((child = g_variant_iter_next_value(&children)) != NULL) {
1620 /* g_debug("Looking at child: %d", position); */1658 /* g_debug("Looking at child: %d", position); */
1621 if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {1659 if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {
1622 child = g_variant_get_variant(child);1660 GVariant * tmp = g_variant_get_variant(child);
1661 g_variant_unref(child);
1662 child = tmp;
1623 }1663 }
16241664
1625 gint childid = g_variant_get_int32(g_variant_get_child_value(child, 0));1665 GVariant * childidv = g_variant_get_child_value(child, 0);
1666 gint childid = g_variant_get_int32(childidv);
1667 g_variant_unref(childidv);
1626 if (childid < 0) {1668 if (childid < 0) {
1627 /* Don't increment the position when there isn't a valid1669 /* Don't increment the position when there isn't a valid
1628 node in the XML tree. It's probably a comment. */1670 node in the XML tree. It's probably a comment. */
1671 g_variant_unref(child);
1629 continue;1672 continue;
1630 }1673 }
1631 DbusmenuMenuitem * childmi = NULL;1674 DbusmenuMenuitem * childmi = NULL;
@@ -1665,10 +1708,12 @@
1665 GVariantIter iter;1708 GVariantIter iter;
1666 gchar * prop;1709 gchar * prop;
1667 GVariant * value;1710 GVariant * value;
1711 GVariant * child_props;
16681712
1669 /* Set the type first as it can manage the behavior of1713 /* Set the type first as it can manage the behavior of
1670 all other properties. */1714 all other properties. */
1671 g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));1715 child_props = g_variant_get_child_value(child, 1);
1716 g_variant_iter_init(&iter, child_props);
1672 while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {1717 while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
1673 if (g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TYPE) == 0) {1718 if (g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TYPE) == 0) {
1674 dbusmenu_menuitem_property_set_variant(childmi, prop, value);1719 dbusmenu_menuitem_property_set_variant(childmi, prop, value);
@@ -1678,15 +1723,17 @@
1678 }1723 }
16791724
1680 /* Now go through and do all the properties. */1725 /* Now go through and do all the properties. */
1681 g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));1726 g_variant_iter_init(&iter, child_props);
1682 while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {1727 while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
1683 dbusmenu_menuitem_property_set_variant(childmi, prop, value);1728 dbusmenu_menuitem_property_set_variant(childmi, prop, value);
1684 g_free(prop);1729 g_free(prop);
1685 g_variant_unref(value);1730 g_variant_unref(value);
1686 }1731 }
1732 g_variant_unref(child_props);
1687 }1733 }
16881734
1689 position++;1735 position++;
1736 g_variant_unref(child);
1690 }1737 }
16911738
1692 /* Remove any children that are no longer used by this version of1739 /* Remove any children that are no longer used by this version of
@@ -1709,19 +1756,24 @@
1709 }1756 }
17101757
1711 /* now it's time to recurse down the tree. */1758 /* now it's time to recurse down the tree. */
1712 g_variant_iter_init(&children, g_variant_get_child_value(layout, 2));1759 g_variant_iter_init(&children, childrenv);
17131760
1714 child = g_variant_iter_next_value(&children);1761 child = g_variant_iter_next_value(&children);
1715 GList * childmis = dbusmenu_menuitem_get_children(item);1762 GList * childmis = dbusmenu_menuitem_get_children(item);
1716 while (child != NULL && childmis != NULL) {1763 while (child != NULL && childmis != NULL) {
1717 if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {1764 if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {
1718 child = g_variant_get_variant(child);1765 GVariant * tmp = g_variant_get_variant(child);
1766 g_variant_unref(child);
1767 child = tmp;
1719 }1768 }
17201769
1721 gint xmlid = g_variant_get_int32(g_variant_get_child_value(child, 0));1770 GVariant * xmlidv = g_variant_get_child_value(child, 0);
1771 gint xmlid = g_variant_get_int32(xmlidv);
1772 g_variant_unref(xmlidv);
1722 /* If this isn't a valid menu item we need to move on1773 /* If this isn't a valid menu item we need to move on
1723 until we have one. This avoids things like comments. */1774 until we have one. This avoids things like comments. */
1724 if (xmlid < 0) {1775 if (xmlid < 0) {
1776 g_variant_unref(child);
1725 child = g_variant_iter_next_value(&children);1777 child = g_variant_iter_next_value(&children);
1726 continue;1778 continue;
1727 }1779 }
@@ -1733,10 +1785,13 @@
1733 1785
1734 parse_layout_xml(client, child, DBUSMENU_MENUITEM(childmis->data), item, proxy);1786 parse_layout_xml(client, child, DBUSMENU_MENUITEM(childmis->data), item, proxy);
17351787
1788 g_variant_unref(child);
1736 child = g_variant_iter_next_value(&children);1789 child = g_variant_iter_next_value(&children);
1737 childmis = g_list_next(childmis);1790 childmis = g_list_next(childmis);
1738 }1791 }
17391792
1793 g_variant_unref(childrenv);
1794
1740 if (child != NULL) {1795 if (child != NULL) {
1741 g_warning("Sync failed, now we've got extra layout nodes.");1796 g_warning("Sync failed, now we've got extra layout nodes.");
1742 }1797 }
@@ -1801,6 +1856,7 @@
18011856
1802 GError * error = NULL;1857 GError * error = NULL;
1803 GVariant * params = NULL;1858 GVariant * params = NULL;
1859 GVariant * layout = NULL;
18041860
1805 params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);1861 params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
18061862
@@ -1810,8 +1866,11 @@
1810 goto out;1866 goto out;
1811 }1867 }
18121868
1813 guint rev = g_variant_get_uint32(g_variant_get_child_value(params, 0));1869 GVariant * revv = g_variant_get_child_value(params, 0);
1814 GVariant * layout = g_variant_get_child_value(params, 1);1870 guint rev = g_variant_get_uint32(revv);
1871 g_variant_unref(revv);
1872
1873 layout = g_variant_get_child_value(params, 1);
18151874
1816 guint parseable = parse_layout(client, layout);1875 guint parseable = parse_layout(client, layout);
18171876
@@ -1839,6 +1898,10 @@
1839 priv->layoutcall = NULL;1898 priv->layoutcall = NULL;
1840 }1899 }
18411900
1901 if (layout != NULL) {
1902 g_variant_unref(layout);
1903 }
1904
1842 if (params != NULL) {1905 if (params != NULL) {
1843 g_variant_unref(params);1906 g_variant_unref(params);
1844 }1907 }

Subscribers

People subscribed via source and target branches