summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2014-06-06 16:17:19 +0900
committerfujiwarat <takao.fujiwara1@gmail.com>2014-06-06 16:17:19 +0900
commitf3e8aaff559e56efe54c43af123e0ab87a17423b (patch)
treed45f36099331640a0f6a8db0603ea8a821df3979 /src
parent87fb61f76fc0ffbac316b0090b206faadfbd82fd (diff)
downloadibus-f3e8aaff559e56efe54c43af123e0ab87a17423b.tar.gz
Fix string leaks in deserialize vfuncs
When an object contains char * properties, its deserialize function will overwrite these string values without freeing them first. They are not necessarily NULL as they can have (default) values set upon construction, so they need to be g_free'd before being overwritten. For example, IBusEngineDesc::longname, IBusEngineDesc::description, IBusEngineDesc::language, ... are all set to "" upon construction (instead of NULL), so the corresponding IBusEngineDesc fields must be freed before being overwritten during deserialization. This commit introduces a ibus_g_variant_get_child_string() to do this and set the string value. This leak was reported by valgrind: ==22163== 59 bytes in 59 blocks are definitely lost in loss record 1,633 of 2,720 ==22163== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==22163== by 0x56DFDF2: g_malloc (gmem.c:97) ==22163== by 0x56E011D: g_malloc_n (gmem.c:338) ==22163== by 0x56FAFCC: g_strdup (gstrfuncs.c:356) ==22163== by 0x546CDB8: g_value_dup_string (gvaluetypes.c:1136) ==22163== by 0x4E43A98: ibus_engine_desc_set_property (ibusenginedesc.c:385) ==22163== by 0x5446CA3: object_set_property (gobject.c:1378) ==22163== by 0x54484BB: g_object_constructor (gobject.c:2020) ==22163== by 0x4E24564: ibus_object_constructor (ibusobject.c:111) ==22163== by 0x5447577: g_object_new_with_custom_constructor (gobject.c:1645) ==22163== by 0x5447787: g_object_new_internal (gobject.c:1722) ==22163== by 0x5447C75: g_object_newv (gobject.c:1868) ==22163== by 0x544737A: g_object_new (gobject.c:1568) ==22163== by 0x4E2521C: ibus_serializable_deserialize (ibusserializable.c:292) ==22163== by 0x4E480E0: ibus_component_deserialize (ibuscomponent.c:408) ==22163== by 0x4E2523E: ibus_serializable_deserialize (ibusserializable.c:294) ==22163== by 0x4E4C1D1: ibus_registry_deserialize (ibusregistry.c:202) ==22163== by 0x4E4C95C: ibus_registry_load_cache_file (ibusregistry.c:362) ==22163== by 0x4E4C6A4: ibus_registry_load_cache (ibusregistry.c:302) ==22163== by 0x40EBCD: bus_ibus_impl_registry_init (ibusimpl.c:1871) ==22163== by 0x40C1D4: bus_ibus_impl_init (ibusimpl.c:424) ==22163== by 0x5460FCD: g_type_create_instance (gtype.c:1868) ==22163== by 0x5448466: g_object_constructor (gobject.c:2006) ==22163== by 0x4E24564: ibus_object_constructor (ibusobject.c:111) ==22163== by 0x5447577: g_object_new_with_custom_constructor (gobject.c:1645) ==22163== by 0x5447787: g_object_new_internal (gobject.c:1722) ==22163== by 0x54483C1: g_object_new_valist (gobject.c:1980) ==22163== by 0x54473C9: g_object_new (gobject.c:1571) ==22163== by 0x40E94A: bus_ibus_impl_get_default (ibusimpl.c:1807) ==22163== by 0x41D880: bus_server_init (server.c:100) ==22163== by 0x420E91: main (main.c:236) BUG=http://code.google.com/p/ibus/issues/detail?id=1712 Review URL: https://codereview.appspot.com/104850043 Patch from Christophe Fergeau <cfergeau@redhat.com>.
Diffstat (limited to 'src')
-rw-r--r--src/ibuscomponent.c25
-rw-r--r--src/ibusenginedesc.c46
-rw-r--r--src/ibusinternal.h3
-rw-r--r--src/ibusobservedpath.c3
-rw-r--r--src/ibusproperty.c3
-rw-r--r--src/ibusutil.c9
6 files changed, 64 insertions, 25 deletions
diff --git a/src/ibuscomponent.c b/src/ibuscomponent.c
index 67b9818a..755e9f65 100644
--- a/src/ibuscomponent.c
+++ b/src/ibuscomponent.c
@@ -21,6 +21,7 @@
*/
#include <glib/gstdio.h>
#include "ibuscomponent.h"
+#include "ibusinternal.h"
enum {
LAST_SIGNAL,
@@ -384,14 +385,22 @@ ibus_component_deserialize (IBusComponent *component,
retval = IBUS_SERIALIZABLE_CLASS (ibus_component_parent_class)->deserialize ((IBusSerializable *)component, variant);
g_return_val_if_fail (retval, 0);
- g_variant_get_child (variant, retval++, "s", &component->priv->name);
- g_variant_get_child (variant, retval++, "s", &component->priv->description);
- g_variant_get_child (variant, retval++, "s", &component->priv->version);
- g_variant_get_child (variant, retval++, "s", &component->priv->license);
- g_variant_get_child (variant, retval++, "s", &component->priv->author);
- g_variant_get_child (variant, retval++, "s", &component->priv->homepage);
- g_variant_get_child (variant, retval++, "s", &component->priv->exec);
- g_variant_get_child (variant, retval++, "s", &component->priv->textdomain);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->name);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->description);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->version);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->license);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->author);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->homepage);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->exec);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &component->priv->textdomain);
GVariant *var;
GVariantIter *iter = NULL;
diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c
index ca488552..f1a04a09 100644
--- a/src/ibusenginedesc.c
+++ b/src/ibusenginedesc.c
@@ -21,6 +21,7 @@
*/
#include <stdlib.h>
#include "ibusenginedesc.h"
+#include "ibusinternal.h"
#include "ibusxml.h"
enum {
@@ -554,29 +555,44 @@ ibus_engine_desc_deserialize (IBusEngineDesc *desc,
* you should not change the serialized order of name, longname,
* description, ... because the order is also used in other applications
* likes ibus-qt. */
- g_variant_get_child (variant, retval++, "s", &desc->priv->name);
- g_variant_get_child (variant, retval++, "s", &desc->priv->longname);
- g_variant_get_child (variant, retval++, "s", &desc->priv->description);
- g_variant_get_child (variant, retval++, "s", &desc->priv->language);
- g_variant_get_child (variant, retval++, "s", &desc->priv->license);
- g_variant_get_child (variant, retval++, "s", &desc->priv->author);
- g_variant_get_child (variant, retval++, "s", &desc->priv->icon);
- g_variant_get_child (variant, retval++, "s", &desc->priv->layout);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->name);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->longname);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->description);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->language);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->license);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->author);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->icon);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->layout);
g_variant_get_child (variant, retval++, "u", &desc->priv->rank);
/* The serialized order should be kept. */
- g_variant_get_child (variant, retval++, "s", &desc->priv->hotkeys);
- g_variant_get_child (variant, retval++, "s", &desc->priv->symbol);
- g_variant_get_child (variant, retval++, "s", &desc->priv->setup);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->hotkeys);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->symbol);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->setup);
if (g_variant_n_children (variant) < retval + 2)
return retval;
- g_variant_get_child (variant, retval++, "s", &desc->priv->layout_variant);
- g_variant_get_child (variant, retval++, "s", &desc->priv->layout_option);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->layout_variant);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->layout_option);
if (g_variant_n_children (variant) < retval + 1)
return retval;
- g_variant_get_child (variant, retval++, "s", &desc->priv->version);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->version);
if (g_variant_n_children (variant) < retval + 1)
return retval;
- g_variant_get_child (variant, retval++, "s", &desc->priv->textdomain);
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->textdomain);
return retval;
}
diff --git a/src/ibusinternal.h b/src/ibusinternal.h
index 1135d8f8..49dc5646 100644
--- a/src/ibusinternal.h
+++ b/src/ibusinternal.h
@@ -68,5 +68,8 @@
*/
#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
+G_GNUC_INTERNAL void
+ibus_g_variant_get_child_string (GVariant *variant, gsize index, char **str);
+
#endif
diff --git a/src/ibusobservedpath.c b/src/ibusobservedpath.c
index dcbfa864..684cd77c 100644
--- a/src/ibusobservedpath.c
+++ b/src/ibusobservedpath.c
@@ -21,6 +21,7 @@
*/
#include <glib/gstdio.h>
#include <stdlib.h>
+#include "ibusinternal.h"
#include "ibusobservedpath.h"
@@ -105,7 +106,7 @@ ibus_observed_path_deserialize (IBusObservedPath *path,
retval = IBUS_SERIALIZABLE_CLASS (ibus_observed_path_parent_class)->deserialize ((IBusSerializable *)path, variant);
g_return_val_if_fail (retval, 0);
- g_variant_get_child (variant, retval++, "s", &path->path);
+ ibus_g_variant_get_child_string (variant, retval++, &path->path);
g_variant_get_child (variant, retval++, "x", &path->mtime);
return retval;
diff --git a/src/ibusproperty.c b/src/ibusproperty.c
index 3abd5e7a..5a3eee03 100644
--- a/src/ibusproperty.c
+++ b/src/ibusproperty.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
+#include "ibusinternal.h"
#include "ibusproperty.h"
#include "ibusproplist.h"
#include "ibusenumtypes.h"
@@ -398,7 +399,7 @@ ibus_property_deserialize (IBusProperty *prop,
retval = IBUS_SERIALIZABLE_CLASS (ibus_property_parent_class)->deserialize ((IBusSerializable *) prop, variant);
g_return_val_if_fail (retval, 0);
- g_variant_get_child (variant, retval++, "s", &prop->priv->key);
+ ibus_g_variant_get_child_string (variant, retval++, &prop->priv->key);
g_variant_get_child (variant, retval++, "u", &prop->priv->type);
GVariant *subvar = g_variant_get_child_value (variant, retval++);
diff --git a/src/ibusutil.c b/src/ibusutil.c
index 215cb3f2..3eddc99c 100644
--- a/src/ibusutil.c
+++ b/src/ibusutil.c
@@ -153,3 +153,12 @@ ibus_get_language_name(const gchar *_locale) {
#endif
}
}
+
+void
+ibus_g_variant_get_child_string (GVariant *variant, gsize index, char **str)
+{
+ g_return_if_fail (str != NULL);
+
+ g_free (*str);
+ g_variant_get_child (variant, index, "s", str);
+}