[librsvg] paint-server: Simplify fallback code
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] paint-server: Simplify fallback code
- Date: Thu, 22 Oct 2015 11:12:29 +0000 (UTC)
commit 1104491df8f6475bb7cc52c8f85f9130f278b737
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 7 10:12:21 2015 +0200
paint-server: Simplify fallback code
Now that we have proper cycle detection in the drawing context, we
should use it.
rsvg-paint-server.c | 109 +++++++++++++--------------------------------------
1 files changed, 27 insertions(+), 82 deletions(-)
---
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 6fe17b3..7845115 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -502,82 +502,41 @@ hasstop (GPtrArray * lookin)
return 0;
}
-typedef const char * (* GetFallbackFn) (gpointer data);
-typedef void (* ApplyFallbackFn) (gpointer data, gpointer fallback_data);
+typedef const char * (* GetFallbackFn) (RsvgNode *node);
+typedef void (* ApplyFallbackFn) (RsvgNode *node, RsvgNode *fallback_node);
/* Some SVG paint servers can reference a "parent" or "fallback" paint server
* through the xlink:href attribute (for example,
* http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute )
* This is used to define a chain of properties to be resolved from each
- * fallback. However, a malicious SVG may have a cycle in the chain of
- * fallbacks, which could lead to an infinite loop when resolving the chain.
- *
- * This is a generic function to apply a chain of fallbacks without cycling; it
- * uses a tortoise-and-hare to detect cycles. The hare moves twice as fast as
- * the tortoise; if they catch up, then there is a cycle and we stop.
- *
- * The parameters are:
- *
- * @data: the paint server to resolve
- * @get_fallback: a function which, given a paint server, will return its fallback (or NULL).
- * This function must make sure that the type of the node it gets passed is correct.
- * @apply_fallback: a function which, given a paint server and a fallback one, will apply
- * the fallback to the paint server as appropriate. This function must
- * ensure that the type of the fallback node it gets passed is correct.
- *
- * We use plain gpointers because this is called from different places with different
- * structure types.
+ * fallback.
*/
static void
resolve_fallbacks (RsvgDrawingCtx *ctx,
- gpointer data,
+ RsvgNode *data,
+ RsvgNode *last_fallback,
GetFallbackFn get_fallback,
ApplyFallbackFn apply_fallback)
{
- gpointer tortoise, hare;
-
- g_assert (data != NULL);
-
- tortoise = data;
- hare = data;
-
- while (hare) {
- gpointer fallback;
- const char *fallback_id;
-
- fallback_id = get_fallback (hare);
- if (fallback_id == NULL)
- break;
- fallback = rsvg_defs_lookup (ctx->defs, fallback_id);
- if (fallback)
- apply_fallback (data, fallback);
-
- hare = fallback;
+ RsvgNode *fallback;
+ const char *fallback_id;
- if (hare) {
- fallback_id = get_fallback (hare);
- if (fallback_id == NULL)
- break;
- fallback = rsvg_defs_lookup (ctx->defs, fallback_id);
- if (fallback)
- apply_fallback (data, fallback);
+ fallback_id = get_fallback (last_fallback);
+ if (fallback_id == NULL)
+ return;
+ fallback = rsvg_acquire_node (ctx, fallback_id);
+ if (fallback == NULL)
+ return;
- hare = fallback;
- }
+ apply_fallback (data, fallback);
+ resolve_fallbacks (ctx, data, fallback, get_fallback, apply_fallback);
- fallback_id = get_fallback (tortoise);
- tortoise = rsvg_defs_lookup (ctx->defs, fallback_id);
- if (tortoise == hare)
- break;
- }
+ rsvg_release_node (ctx, fallback);
}
static const char *
-gradient_get_fallback (gpointer data)
+gradient_get_fallback (RsvgNode *node)
{
- RsvgNode *node;
-
- node = data;
if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
RsvgLinearGradient *g = (RsvgLinearGradient *) node;
return g->fallback;
@@ -589,18 +548,13 @@ gradient_get_fallback (gpointer data)
}
static void
-linear_gradient_apply_fallback (gpointer data, gpointer fallback_data)
+linear_gradient_apply_fallback (RsvgNode *node, RsvgNode *fallback_node)
{
- RsvgNode *node;
RsvgLinearGradient *grad;
- RsvgNode *fallback_node;
- node = data;
g_assert (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT);
grad = (RsvgLinearGradient *) node;
- fallback_node = fallback_data;
-
if (RSVG_NODE_TYPE (fallback_node) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
RsvgLinearGradient *fallback = (RsvgLinearGradient *) fallback_node;
@@ -660,24 +614,20 @@ void
rsvg_linear_gradient_fix_fallback (RsvgDrawingCtx *ctx, RsvgLinearGradient * grad)
{
resolve_fallbacks (ctx,
- grad,
+ (RsvgNode *) grad,
+ (RsvgNode *) grad,
gradient_get_fallback,
linear_gradient_apply_fallback);
}
static void
-radial_gradient_apply_fallback (gpointer data, gpointer fallback_data)
+radial_gradient_apply_fallback (RsvgNode *node, RsvgNode *fallback_node)
{
- RsvgNode *node;
RsvgRadialGradient *grad;
- RsvgNode *fallback_node;
- node = data;
g_assert (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_RADIAL_GRADIENT);
grad = (RsvgRadialGradient *) node;
- fallback_node = fallback_data;
-
if (RSVG_NODE_TYPE (fallback_node) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
RsvgRadialGradient *fallback = (RsvgRadialGradient *) fallback_node;
@@ -741,16 +691,15 @@ void
rsvg_radial_gradient_fix_fallback (RsvgDrawingCtx *ctx, RsvgRadialGradient * grad)
{
resolve_fallbacks (ctx,
- grad,
+ (RsvgNode *) grad,
+ (RsvgNode *) grad,
gradient_get_fallback,
radial_gradient_apply_fallback);
}
static const char *
-pattern_get_fallback (gpointer data)
+pattern_get_fallback (RsvgNode *node)
{
- RsvgNode *node = data;
-
if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_PATTERN) {
RsvgPattern *pattern = (RsvgPattern *) node;
@@ -760,16 +709,11 @@ pattern_get_fallback (gpointer data)
}
static void
-pattern_apply_fallback (gpointer data, gpointer fallback_data)
+pattern_apply_fallback (RsvgNode *pattern_node, RsvgNode *fallback_node)
{
- RsvgNode *pattern_node;
RsvgPattern *pattern;
- RsvgNode *fallback_node;
RsvgPattern *fallback;
- pattern_node = data;
- fallback_node = fallback_data;
-
g_assert (RSVG_NODE_TYPE (pattern_node) == RSVG_NODE_TYPE_PATTERN);
if (RSVG_NODE_TYPE (fallback_node) != RSVG_NODE_TYPE_PATTERN)
@@ -822,7 +766,8 @@ void
rsvg_pattern_fix_fallback (RsvgDrawingCtx *ctx, RsvgPattern * pattern)
{
resolve_fallbacks (ctx,
- pattern,
+ (RsvgNode *) pattern,
+ (RsvgNode *) pattern,
pattern_get_fallback,
pattern_apply_fallback);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]