Container: Don’t scroll to unset focus child coord

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
This commit is contained in:
Daniel Boles
2017-08-07 18:43:31 +01:00
parent 12805a4fbf
commit cf955a5459

View File

@ -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;