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.
This commit is contained in:
Benjamin Otte
2013-03-28 23:13:43 +01:00
parent c25d8e3aea
commit cbee390148
6 changed files with 26 additions and 12 deletions

View File

@ -342,7 +342,8 @@ _gtk_gradient_resolve_full (GtkGradient *gradient,
provider, provider,
_gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR),
GTK_CSS_DEPENDS_ON_COLOR, GTK_CSS_DEPENDS_ON_COLOR,
&stop_deps); &stop_deps,
NULL);
if (val) if (val)
{ {
rgba = *_gtk_css_rgba_value_get_rgba (val); rgba = *_gtk_css_rgba_value_get_rgba (val);

View File

@ -307,6 +307,7 @@ gtk_symbolic_color_resolve (GtkSymbolicColor *color,
GTK_STYLE_PROVIDER_PRIVATE (props), GTK_STYLE_PROVIDER_PRIVATE (props),
current, current,
0, 0,
NULL,
NULL); NULL);
_gtk_css_value_unref (current); _gtk_css_value_unref (current);
if (v == NULL) if (v == NULL)

View File

@ -140,7 +140,8 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
GtkStyleProviderPrivate *provider, GtkStyleProviderPrivate *provider,
GtkCssValue *current, GtkCssValue *current,
GtkCssDependencies current_deps, GtkCssDependencies current_deps,
GtkCssDependencies *dependencies) GtkCssDependencies *dependencies,
GSList *cycle_list)
{ {
GtkCssDependencies unused; GtkCssDependencies unused;
GtkCssValue *value; GtkCssValue *value;
@ -160,12 +161,18 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
case COLOR_TYPE_NAME: case COLOR_TYPE_NAME:
{ {
GtkCssValue *named; 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); named = _gtk_style_provider_private_get_color (provider, color->sym_col.name);
if (named == NULL) if (named == NULL)
return 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) if (value == NULL)
return NULL; return NULL;
} }
@ -177,7 +184,7 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
GtkHSLA hsla; GtkHSLA hsla;
GdkRGBA shade; 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) if (val == NULL)
return NULL; return NULL;
@ -199,7 +206,7 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
GtkCssValue *val; GtkCssValue *val;
GdkRGBA alpha; 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) if (val == NULL)
return NULL; return NULL;
@ -219,13 +226,13 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
GdkRGBA color1, color2, res; GdkRGBA color1, color2, res;
GtkCssDependencies dep1, dep2; 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) if (val == NULL)
return NULL; return NULL;
color1 = *_gtk_css_rgba_value_get_rgba (val); color1 = *_gtk_css_rgba_value_get_rgba (val);
_gtk_css_value_unref (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) if (val == NULL)
return NULL; return NULL;
color2 = *_gtk_css_rgba_value_get_rgba (val); color2 = *_gtk_css_rgba_value_get_rgba (val);
@ -324,7 +331,8 @@ gtk_css_value_color_compute (GtkCssValue *value,
provider, provider,
current, current,
current_deps, current_deps,
dependencies); dependencies,
NULL);
if (resolved == NULL) if (resolved == NULL)
return gtk_css_value_color_get_fallback (property_id, provider, values, parent_values); return gtk_css_value_color_get_fallback (property_id, provider, values, parent_values);

View File

@ -47,7 +47,8 @@ GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue
GtkStyleProviderPrivate *provider, GtkStyleProviderPrivate *provider,
GtkCssValue *current, GtkCssValue *current,
GtkCssDependencies current_deps, GtkCssDependencies current_deps,
GtkCssDependencies *dependencies); GtkCssDependencies *dependencies,
GSList *cycle_list);
G_END_DECLS G_END_DECLS

View File

@ -234,7 +234,8 @@ rgba_value_compute (GtkStyleProviderPrivate *provider,
provider, provider,
_gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR),
GTK_CSS_DEPENDS_ON_COLOR, GTK_CSS_DEPENDS_ON_COLOR,
dependencies); dependencies,
NULL);
if (val != NULL) if (val != NULL)
{ {
rgba = *_gtk_css_rgba_value_get_rgba (val); rgba = *_gtk_css_rgba_value_get_rgba (val);
@ -323,7 +324,8 @@ color_value_compute (GtkStyleProviderPrivate *provider,
provider, provider,
_gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR),
GTK_CSS_DEPENDS_ON_COLOR, GTK_CSS_DEPENDS_ON_COLOR,
dependencies); dependencies,
NULL);
if (val != NULL) if (val != NULL)
{ {
const GdkRGBA *rgba = _gtk_css_rgba_value_get_rgba (val); const GdkRGBA *rgba = _gtk_css_rgba_value_get_rgba (val);

View File

@ -2827,7 +2827,8 @@ _gtk_style_context_resolve_color (GtkStyleContext *context,
GTK_STYLE_PROVIDER_PRIVATE (context->priv->cascade), GTK_STYLE_PROVIDER_PRIVATE (context->priv->cascade),
_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR), _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR),
GTK_CSS_DEPENDS_ON_COLOR, GTK_CSS_DEPENDS_ON_COLOR,
dependencies); dependencies,
NULL);
if (val == NULL) if (val == NULL)
return FALSE; return FALSE;