From cf955a545969346b350d9f941bd092f0f3879581 Mon Sep 17 00:00:00 2001 From: Daniel Boles Date: Mon, 7 Aug 2017 18:43:31 +0100 Subject: [PATCH] =?UTF-8?q?Container:=20Don=E2=80=99t=20scroll=20to=20unse?= =?UTF-8?q?t=20focus=20child=20coord?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In gtk_container_real_set_focus_child(), we try to scroll to the position of the new :focus-child if we have h or v adjustments. gtk_widget_translate_coordinates() returns FALSE if neither widget is realized or in other situations that cause output parameters x and y not to be set. Thus, if the caller did not initialise x/y and uses them even if the function returns FALSE, they are using uninitialised variables. In gtk_container_real_set_focus_child(), we did not check the return value but merrily went ahead and used x and y regardless. This is UB, as caught by Valgrind, as well as being pointless. The trivial fix is to exit early if (!gtk_widget_translate_coordinates). https://bugzilla.gnome.org/show_bug.cgi?id=776909 --- gtk/gtkcontainer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 55201eed1d..4d907d1004 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -2680,14 +2680,14 @@ gtk_container_real_set_focus_child (GtkContainer *container, { if (priv->focus_child) g_object_unref (priv->focus_child); + priv->focus_child = child; + if (priv->focus_child) g_object_ref (priv->focus_child); } - - /* check for h/v adjustments - */ + /* Check for h/v adjustments and scroll to show the focus child if possible */ if (priv->focus_child) { GtkAdjustment *hadj; @@ -2700,15 +2700,15 @@ gtk_container_real_set_focus_child (GtkContainer *container, vadj = g_object_get_qdata (G_OBJECT (container), vadjustment_key_id); if (hadj || vadj) { - focus_child = priv->focus_child; while (GTK_IS_CONTAINER (focus_child) && gtk_container_get_focus_child (GTK_CONTAINER (focus_child))) { focus_child = gtk_container_get_focus_child (GTK_CONTAINER (focus_child)); } - gtk_widget_translate_coordinates (focus_child, priv->focus_child, - 0, 0, &x, &y); + if (!gtk_widget_translate_coordinates (focus_child, priv->focus_child, + 0, 0, &x, &y)) + return; _gtk_widget_get_allocation (priv->focus_child, &allocation); x += allocation.x;