From 83d6c38e0c476894d604ddb55a149284d37d4d39 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 3 Jan 2017 15:48:46 -0800 Subject: [PATCH] subprocess: avoid infinite loop in verify_disposition() When performing the verify and building the error string there were two possibilities of an infinite loop. The first is the missing twos-complement to unset the bit in the filtered flags. The second is the lack of handling G_SUBPROCESS_FLAGS_NONE which can return a valid GFlagsValue (and cannot unset the bit since the value is zero). This walks all known values in the GSubprocessFlags type class and check if they are set. This has the benefit that we don't call needless functions which walk the same table as well as avoiding mutating values to build the error string. https://bugzilla.gnome.org/show_bug.cgi?id=775913 --- gio/gsubprocesslauncher.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gio/gsubprocesslauncher.c b/gio/gsubprocesslauncher.c index a7906d9d3..d43583af7 100644 --- a/gio/gsubprocesslauncher.c +++ b/gio/gsubprocesslauncher.c @@ -79,13 +79,16 @@ verify_disposition (const gchar *stream_name, if (n_bits) { GFlagsClass *class; - GFlagsValue *value; + guint i; class = g_type_class_peek (G_TYPE_SUBPROCESS_FLAGS); - while ((value = g_flags_get_first_value (class, filtered_flags))) + + for (i = 0; i < class->n_values; i++) { - g_string_append_printf (err, " %s", value->value_name); - filtered_flags &= value->value; + const GFlagsValue *value = &class->values[i]; + + if (filtered_flags & value->value) + g_string_append_printf (err, " %s", value->value_name); } g_type_class_unref (class);