From cbee3901486781370f50ee02f49bdbd463f3eaa3 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 28 Mar 2013 23:13:43 +0100 Subject: [PATCH] cssvalue: At cycle detection to color resolving The following CSS would infloop: @define-color self @self as it would infinitely lookup the color named "self" and try to resolve it. This patch adds detection of such cycles to the resolve function by keeping a list of currently resolving colors in the cycle_list variable. --- gtk/deprecated/gtkgradient.c | 3 ++- gtk/deprecated/gtksymboliccolor.c | 1 + gtk/gtkcsscolorvalue.c | 22 +++++++++++++++------- gtk/gtkcsscolorvalueprivate.h | 3 ++- gtk/gtkcssstylefuncs.c | 6 ++++-- gtk/gtkstylecontext.c | 3 ++- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/gtk/deprecated/gtkgradient.c b/gtk/deprecated/gtkgradient.c index 78cf7a3bfc..9a0dd64d3c 100644 --- a/gtk/deprecated/gtkgradient.c +++ b/gtk/deprecated/gtkgradient.c @@ -342,7 +342,8 @@ _gtk_gradient_resolve_full (GtkGradient *gradient, provider, _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), GTK_CSS_DEPENDS_ON_COLOR, - &stop_deps); + &stop_deps, + NULL); if (val) { rgba = *_gtk_css_rgba_value_get_rgba (val); diff --git a/gtk/deprecated/gtksymboliccolor.c b/gtk/deprecated/gtksymboliccolor.c index db85a3b1b6..ef60974077 100644 --- a/gtk/deprecated/gtksymboliccolor.c +++ b/gtk/deprecated/gtksymboliccolor.c @@ -307,6 +307,7 @@ gtk_symbolic_color_resolve (GtkSymbolicColor *color, GTK_STYLE_PROVIDER_PRIVATE (props), current, 0, + NULL, NULL); _gtk_css_value_unref (current); if (v == NULL) diff --git a/gtk/gtkcsscolorvalue.c b/gtk/gtkcsscolorvalue.c index 64933bde58..d523fe82d4 100644 --- a/gtk/gtkcsscolorvalue.c +++ b/gtk/gtkcsscolorvalue.c @@ -140,7 +140,8 @@ _gtk_css_color_value_resolve (GtkCssValue *color, GtkStyleProviderPrivate *provider, GtkCssValue *current, GtkCssDependencies current_deps, - GtkCssDependencies *dependencies) + GtkCssDependencies *dependencies, + GSList *cycle_list) { GtkCssDependencies unused; GtkCssValue *value; @@ -160,12 +161,18 @@ _gtk_css_color_value_resolve (GtkCssValue *color, case COLOR_TYPE_NAME: { GtkCssValue *named; + GSList cycle = { color, cycle_list }; + + /* If color exists in cycle_list, we're currently resolving it. + * So we've detected a cycle. */ + if (g_slist_find (cycle_list, color)) + return NULL; named = _gtk_style_provider_private_get_color (provider, color->sym_col.name); if (named == NULL) return NULL; - value = _gtk_css_color_value_resolve (named, provider, current, current_deps, dependencies); + value = _gtk_css_color_value_resolve (named, provider, current, current_deps, dependencies, &cycle); if (value == NULL) return NULL; } @@ -177,7 +184,7 @@ _gtk_css_color_value_resolve (GtkCssValue *color, GtkHSLA hsla; GdkRGBA shade; - val = _gtk_css_color_value_resolve (color->sym_col.shade.color, provider, current, current_deps, dependencies); + val = _gtk_css_color_value_resolve (color->sym_col.shade.color, provider, current, current_deps, dependencies, cycle_list); if (val == NULL) return NULL; @@ -199,7 +206,7 @@ _gtk_css_color_value_resolve (GtkCssValue *color, GtkCssValue *val; GdkRGBA alpha; - val = _gtk_css_color_value_resolve (color->sym_col.alpha.color, provider, current, current_deps, dependencies); + val = _gtk_css_color_value_resolve (color->sym_col.alpha.color, provider, current, current_deps, dependencies, cycle_list); if (val == NULL) return NULL; @@ -219,13 +226,13 @@ _gtk_css_color_value_resolve (GtkCssValue *color, GdkRGBA color1, color2, res; GtkCssDependencies dep1, dep2; - val = _gtk_css_color_value_resolve (color->sym_col.mix.color1, provider, current, current_deps, &dep1); + val = _gtk_css_color_value_resolve (color->sym_col.mix.color1, provider, current, current_deps, &dep1, cycle_list); if (val == NULL) return NULL; color1 = *_gtk_css_rgba_value_get_rgba (val); _gtk_css_value_unref (val); - val = _gtk_css_color_value_resolve (color->sym_col.mix.color2, provider, current, current_deps, &dep2); + val = _gtk_css_color_value_resolve (color->sym_col.mix.color2, provider, current, current_deps, &dep2, cycle_list); if (val == NULL) return NULL; color2 = *_gtk_css_rgba_value_get_rgba (val); @@ -324,7 +331,8 @@ gtk_css_value_color_compute (GtkCssValue *value, provider, current, current_deps, - dependencies); + dependencies, + NULL); if (resolved == NULL) return gtk_css_value_color_get_fallback (property_id, provider, values, parent_values); diff --git a/gtk/gtkcsscolorvalueprivate.h b/gtk/gtkcsscolorvalueprivate.h index 06e6a1cd0e..4392a0799d 100644 --- a/gtk/gtkcsscolorvalueprivate.h +++ b/gtk/gtkcsscolorvalueprivate.h @@ -47,7 +47,8 @@ GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue GtkStyleProviderPrivate *provider, GtkCssValue *current, GtkCssDependencies current_deps, - GtkCssDependencies *dependencies); + GtkCssDependencies *dependencies, + GSList *cycle_list); G_END_DECLS diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c index af1c1b1b6f..1dff511d59 100644 --- a/gtk/gtkcssstylefuncs.c +++ b/gtk/gtkcssstylefuncs.c @@ -234,7 +234,8 @@ rgba_value_compute (GtkStyleProviderPrivate *provider, provider, _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), GTK_CSS_DEPENDS_ON_COLOR, - dependencies); + dependencies, + NULL); if (val != NULL) { rgba = *_gtk_css_rgba_value_get_rgba (val); @@ -323,7 +324,8 @@ color_value_compute (GtkStyleProviderPrivate *provider, provider, _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), GTK_CSS_DEPENDS_ON_COLOR, - dependencies); + dependencies, + NULL); if (val != NULL) { const GdkRGBA *rgba = _gtk_css_rgba_value_get_rgba (val); diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index f2c79c8d2e..0a0f4b1fce 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -2827,7 +2827,8 @@ _gtk_style_context_resolve_color (GtkStyleContext *context, GTK_STYLE_PROVIDER_PRIVATE (context->priv->cascade), _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR), GTK_CSS_DEPENDS_ON_COLOR, - dependencies); + dependencies, + NULL); if (val == NULL) return FALSE;