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:
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user