diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-07-12 08:48:25 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-07-12 08:48:29 +0900 |
commit | 54ced30b5b9a8471d9d7af4dc3e8c2d0f7b013e8 (patch) | |
tree | 0c4937bc64caaf497c496d43468708772a2f3eec /gi/gimodule.c | |
parent | 2af8b46dbcf9e73f2ca40ea26cab5ab7ccac5d2a (diff) | |
download | pygobject2-54ced30b5b9a8471d9d7af4dc3e8c2d0f7b013e8.tar.gz pygobject2-54ced30b5b9a8471d9d7af4dc3e8c2d0f7b013e8.tar.bz2 pygobject2-54ced30b5b9a8471d9d7af4dc3e8c2d0f7b013e8.zip |
Imported Upstream version 3.7.4
Change-Id: Ida7f0ffc68fbd0b3af016f7988b2210cdf9afa1a
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'gi/gimodule.c')
-rw-r--r-- | gi/gimodule.c | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/gi/gimodule.c b/gi/gimodule.c index 76530f1..bb5c306 100644 --- a/gi/gimodule.c +++ b/gi/gimodule.c @@ -62,7 +62,9 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self, gint n_values; GEnumValue *g_enum_values; int i; + const gchar *namespace; const gchar *type_name; + gchar *full_name; GType g_type; if (!PyArg_ParseTupleAndKeywords (args, kwargs, @@ -79,6 +81,10 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self, info = (GIEnumInfo *)py_info->info; n_values = g_enum_info_get_n_values (info); + + /* The new memory is zero filled which fulfills the registration + * function requirement that the last item is zeroed out as a terminator. + */ g_enum_values = g_new0 (GEnumValue, n_values + 1); for (i = 0; i < n_values; i++) { @@ -105,14 +111,36 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self, g_base_info_unref ((GIBaseInfo *) value_info); } - g_enum_values[n_values].value = 0; - g_enum_values[n_values].value_nick = NULL; - g_enum_values[n_values].value_name = NULL; - + namespace = g_base_info_get_namespace ((GIBaseInfo *) info); type_name = g_base_info_get_name ((GIBaseInfo *) info); - type_name = g_strdup (type_name); - g_type = g_enum_register_static (type_name, g_enum_values); + full_name = g_strconcat (namespace, type_name, NULL); + + /* If enum registration fails, free all the memory allocated + * for the values array. This needs to leak when successful + * as GObject keeps a reference to the data as specified in the docs. + */ + g_type = g_enum_register_static (full_name, g_enum_values); + if (g_type == G_TYPE_INVALID) { + for (i = 0; i < n_values; i++) { + GEnumValue *enum_value = &g_enum_values[i]; + + /* Only free value_name if it is different from value_nick to avoid + * a double free. The pointer might have been is re-used in the case + * c_identifier was NULL in the above loop. + */ + if (enum_value->value_name != enum_value->value_nick) + g_free ((gchar *) enum_value->value_name); + g_free ((gchar *) enum_value->value_nick); + } + + PyErr_Format (PyExc_RuntimeError, "Unable to register enum '%s'", full_name); + + g_free (g_enum_values); + g_free (full_name); + return NULL; + } + g_free (full_name); return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type); } @@ -150,7 +178,9 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self, gint n_values; GFlagsValue *g_flags_values; int i; + const gchar *namespace; const gchar *type_name; + gchar *full_name; GType g_type; if (!PyArg_ParseTupleAndKeywords (args, kwargs, @@ -167,6 +197,10 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self, info = (GIEnumInfo *)py_info->info; n_values = g_enum_info_get_n_values (info); + + /* The new memory is zero filled which fulfills the registration + * function requirement that the last item is zeroed out as a terminator. + */ g_flags_values = g_new0 (GFlagsValue, n_values + 1); for (i = 0; i < n_values; i++) { @@ -193,14 +227,36 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self, g_base_info_unref ((GIBaseInfo *) value_info); } - g_flags_values[n_values].value = 0; - g_flags_values[n_values].value_nick = NULL; - g_flags_values[n_values].value_name = NULL; - + namespace = g_base_info_get_namespace ((GIBaseInfo *) info); type_name = g_base_info_get_name ((GIBaseInfo *) info); - type_name = g_strdup (type_name); - g_type = g_flags_register_static (type_name, g_flags_values); + full_name = g_strconcat (namespace, type_name, NULL); + + /* If enum registration fails, free all the memory allocated + * for the values array. This needs to leak when successful + * as GObject keeps a reference to the data as specified in the docs. + */ + g_type = g_flags_register_static (full_name, g_flags_values); + if (g_type == G_TYPE_INVALID) { + for (i = 0; i < n_values; i++) { + GFlagsValue *flags_value = &g_flags_values[i]; + + /* Only free value_name if it is different from value_nick to avoid + * a double free. The pointer might have been is re-used in the case + * c_identifier was NULL in the above loop. + */ + if (flags_value->value_name != flags_value->value_nick) + g_free ((gchar *) flags_value->value_name); + g_free ((gchar *) flags_value->value_nick); + } + + PyErr_Format (PyExc_RuntimeError, "Unable to register flags '%s'", full_name); + + g_free (g_flags_values); + g_free (full_name); + return NULL; + } + g_free (full_name); return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type); } |