st/widget: Don't allow adding/removing "" style class

strstr() in find_class_name() will always consider "" a match so the
loop was not stopping at the end of the class_list. None of the matches
within the class_list would satisfy the return conditions, unless the
class_list was either an empty string as well or has a trailing space.
So this ends up with a match outside of the allocated string that
happens to satisfy these conditions by chance which then leads to the
class string containing some of this unrelated memory. Or it might lead
to a segfault.

This adds checks to the public API that uses find_class_name() to
prevent extensions from accidentally triggering a crash this way or
having some otherwise unexpected results.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7152
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3006>
This commit is contained in:
Sebastian Keller 2023-11-03 10:07:42 +01:00 committed by Florian Müllner
parent c8dae24645
commit dc931e82cd

View File

@ -1199,6 +1199,7 @@ st_widget_add_style_class_name (StWidget *actor,
g_return_if_fail (ST_IS_WIDGET (actor));
g_return_if_fail (style_class != NULL);
g_return_if_fail (style_class[0] != '\0');
priv = st_widget_get_instance_private (actor);
@ -1225,6 +1226,7 @@ st_widget_remove_style_class_name (StWidget *actor,
g_return_if_fail (ST_IS_WIDGET (actor));
g_return_if_fail (style_class != NULL);
g_return_if_fail (style_class[0] != '\0');
priv = st_widget_get_instance_private (actor);
@ -1269,6 +1271,8 @@ st_widget_has_style_class_name (StWidget *actor,
StWidgetPrivate *priv;
g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);
g_return_val_if_fail (style_class != NULL, FALSE);
g_return_val_if_fail (style_class[0] != '\0', FALSE);
priv = st_widget_get_instance_private (actor);
@ -1313,6 +1317,8 @@ st_widget_has_style_pseudo_class (StWidget *actor,
StWidgetPrivate *priv;
g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);
g_return_val_if_fail (pseudo_class != NULL, FALSE);
g_return_val_if_fail (pseudo_class[0] != '\0', FALSE);
priv = st_widget_get_instance_private (actor);
@ -1362,6 +1368,7 @@ st_widget_add_style_pseudo_class (StWidget *actor,
g_return_if_fail (ST_IS_WIDGET (actor));
g_return_if_fail (pseudo_class != NULL);
g_return_if_fail (pseudo_class[0] != '\0');
priv = st_widget_get_instance_private (actor);
@ -1387,6 +1394,7 @@ st_widget_remove_style_pseudo_class (StWidget *actor,
g_return_if_fail (ST_IS_WIDGET (actor));
g_return_if_fail (pseudo_class != NULL);
g_return_if_fail (pseudo_class[0] != '\0');
priv = st_widget_get_instance_private (actor);