diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2023-03-20 21:56:57 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gmail.com> | 2023-03-20 23:23:33 +0000 |
commit | cf92ce290943b7ada40983a08a45f9ef67149c91 (patch) | |
tree | 7527aba2939f875fd4df020d8383ab3cb14181e1 | |
parent | 3af7bf9410ac1f2755b435704f41d9efab1e58eb (diff) | |
download | gobject-introspection-cf92ce290943b7ada40983a08a45f9ef67149c91.tar.gz |
Special-case pointer-sized value types
GValues containing pointer-sized things can hold a NULL value, and
various transformation functions in the wild are not NULL safe.
Fixes: #457
See also: https://gitlab.gnome.org/GNOME/mutter/-/issues/2625
-rw-r--r-- | girepository/gdump.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/girepository/gdump.c b/girepository/gdump.c index a4ff42aa..055a8b8c 100644 --- a/girepository/gdump.c +++ b/girepository/gdump.c @@ -119,6 +119,27 @@ invoke_error_quark (GModule *self, const char *symbol, GError **error) return sym (); } +static char * +value_transform_to_string (const GValue *value) +{ + GValue tmp = G_VALUE_INIT; + char *s = NULL; + + g_value_init (&tmp, G_TYPE_STRING); + + if (g_value_transform (value, &tmp)) + { + const char *str = g_value_get_string (&tmp); + + if (str != NULL) + s = g_strescape (str, NULL); + } + + g_value_unset (&tmp); + + return s; +} + /* A simpler version of g_strdup_value_contents(), but with stable * output and less complex semantics */ @@ -137,25 +158,35 @@ value_to_string (const GValue *value) return g_strescape (s, NULL); } - else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) + else { - GValue tmp = G_VALUE_INIT; - char *s = NULL; + GType value_type = G_VALUE_TYPE (value); - g_value_init (&tmp, G_TYPE_STRING); + switch (G_TYPE_FUNDAMENTAL (value_type)) + { + case G_TYPE_BOXED: + if (g_value_get_boxed (value) == NULL) + return NULL; + else + return value_transform_to_string (value); + break; - if (g_value_transform (value, &tmp)) - s = g_strescape (g_value_get_string (&tmp), NULL); + case G_TYPE_OBJECT: + if (g_value_get_object (value) == NULL) + return NULL; + else + return value_transform_to_string (value); + break; - g_value_unset (&tmp); + case G_TYPE_POINTER: + return NULL; - if (s == NULL) - return NULL; - - return s; + default: + return value_transform_to_string (value); + } } - else - return NULL; + + return NULL; } static void |