Mozilla/mozilla/gfx/cairo/dash-dos.diff
tor%cs.brown.edu e59971ab47 Bug 288498 - Prevent SVG DOS with dasharray
git-svn-id: svn://10.0.0.236/trunk@171430 18797224-902f-48f8-a5cc-f745e15eee43
2005-03-31 20:14:05 +00:00

346 lines
9.4 KiB
Diff

Index: cairo_gstate.c
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.3
diff -u -8 -p -r1.3 cairo_gstate.c
--- cairo_gstate.c 30 Mar 2005 17:32:16 -0000 1.3
+++ cairo_gstate.c 31 Mar 2005 19:53:08 -0000
@@ -84,16 +84,18 @@ _cairo_gstate_init (cairo_gstate_t *gsta
gstate->line_join = CAIRO_GSTATE_LINE_JOIN_DEFAULT;
gstate->miter_limit = CAIRO_GSTATE_MITER_LIMIT_DEFAULT;
gstate->fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT;
gstate->dash = NULL;
gstate->num_dashes = 0;
gstate->dash_offset = 0.0;
+ gstate->max_dash_length = 0.0;
+ gstate->fraction_dash_lit = 0.0;
gstate->font_family = NULL;
gstate->font_slant = CAIRO_FONT_SLANT_DEFAULT;
gstate->font_weight = CAIRO_FONT_WEIGHT_DEFAULT;
gstate->font = NULL;
gstate->surface = NULL;
@@ -538,28 +540,41 @@ cairo_line_join_t
_cairo_gstate_current_line_join (cairo_gstate_t *gstate)
{
return gstate->line_join;
}
cairo_status_t
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset)
{
+ double length = 0.0, lit = 0.0;
+ int i;
+
if (gstate->dash) {
free (gstate->dash);
gstate->dash = NULL;
}
gstate->num_dashes = num_dashes;
if (gstate->num_dashes) {
gstate->dash = malloc (gstate->num_dashes * sizeof (double));
if (gstate->dash == NULL) {
gstate->num_dashes = 0;
return CAIRO_STATUS_NO_MEMORY;
}
+
+ gstate->max_dash_length = 0.0;
+ for (i = 0; i < num_dashes; i++) {
+ gstate->max_dash_length = MAX(dash[i], gstate->max_dash_length);
+
+ if (!(i & 1))
+ lit += dash[i];
+ length += dash[i];
+ }
+ gstate->fraction_dash_lit = lit/length;
}
memcpy (gstate->dash, dash, gstate->num_dashes * sizeof (double));
gstate->dash_offset = offset;
return CAIRO_STATUS_SUCCESS;
}
@@ -1317,46 +1332,77 @@ _cairo_gstate_pattern_init_copy (cairo_g
cairo_pattern_union_t *pattern,
cairo_pattern_t *src)
{
_cairo_pattern_init_copy (&pattern->base, src);
_cairo_pattern_transform (&pattern->base, &gstate->ctm_inverse);
_cairo_pattern_set_alpha (&pattern->base, gstate->alpha);
}
+static cairo_bool_t
+_dashes_invisible (cairo_gstate_t *gstate)
+{
+ if (gstate->dash) {
+ double min, max;
+
+ _cairo_matrix_compute_expansion_factors (&gstate->ctm, &min, &max);
+
+ /* Quick and dirty applicaton of Nyquist sampling limit */
+
+ if (min * gstate->max_dash_length < 0.5f)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
cairo_status_t
_cairo_gstate_stroke (cairo_gstate_t *gstate)
{
cairo_status_t status;
cairo_traps_t traps;
+ double *dash = NULL;
+ double alpha = 0.0;
if (gstate->line_width <= 0.0)
return CAIRO_STATUS_SUCCESS;
+ if (_dashes_invisible(gstate)) {
+ dash = gstate->dash;
+ gstate->dash = NULL;
+
+ alpha = gstate->alpha;
+ gstate->alpha *= gstate->fraction_dash_lit;
+ }
+
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
_cairo_traps_init (&traps);
status = _cairo_path_stroke_to_traps (&gstate->path, gstate, &traps);
- if (status) {
- _cairo_traps_fini (&traps);
- return status;
- }
+ if (status)
+ goto BAIL;
_cairo_gstate_clip_and_composite_trapezoids (gstate,
gstate->pattern,
gstate->operator,
gstate->surface,
&traps);
+ BAIL:
_cairo_traps_fini (&traps);
_cairo_gstate_new_path (gstate);
- return CAIRO_STATUS_SUCCESS;
+ if (dash) {
+ gstate->dash = dash;
+ gstate->alpha = alpha;
+ }
+
+ return status;
}
cairo_status_t
_cairo_gstate_in_stroke (cairo_gstate_t *gstate,
double x,
double y,
cairo_bool_t *inside_ret)
{
@@ -1695,19 +1741,25 @@ _cairo_gstate_show_page (cairo_gstate_t
cairo_status_t
_cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
double *x1, double *y1,
double *x2, double *y2)
{
cairo_status_t status;
cairo_traps_t traps;
cairo_box_t extents;
+ double *dash = NULL;
+
+ if (_dashes_invisible(gstate)) {
+ dash = gstate->dash;
+ gstate->dash = NULL;
+ }
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
-
+
_cairo_traps_init (&traps);
status = _cairo_path_stroke_to_traps (&gstate->path, gstate, &traps);
if (status)
goto BAIL;
_cairo_traps_extents (&traps, &extents);
@@ -1716,16 +1768,19 @@ _cairo_gstate_stroke_extents (cairo_gsta
*x2 = _cairo_fixed_to_double (extents.p2.x);
*y2 = _cairo_fixed_to_double (extents.p2.y);
cairo_matrix_transform_point (&gstate->ctm_inverse, x1, y1);
cairo_matrix_transform_point (&gstate->ctm_inverse, x2, y2);
BAIL:
_cairo_traps_fini (&traps);
+
+ if (dash)
+ gstate->dash = dash;
return status;
}
cairo_status_t
_cairo_gstate_fill_extents (cairo_gstate_t *gstate,
double *x1, double *y1,
double *x2, double *y2)
Index: cairo_matrix.c
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo_matrix.c,v
retrieving revision 1.2
diff -u -8 -p -r1.2 cairo_matrix.c
--- cairo_matrix.c 23 Mar 2005 19:53:39 -0000 1.2
+++ cairo_matrix.c 31 Mar 2005 19:53:08 -0000
@@ -615,16 +615,39 @@ _cairo_matrix_compute_scale_factors (cai
*sx = minor;
*sy = major;
}
}
return CAIRO_STATUS_SUCCESS;
}
+/* Compute the min/max expansion factors. See the comment in
+ * cairo-pen.c for the derivation */
+cairo_status_t
+_cairo_matrix_compute_expansion_factors (cairo_matrix_t *matrix,
+ double *min, double *max)
+{
+ double a = matrix->m[0][0], c = matrix->m[0][1];
+ double b = matrix->m[1][0], d = matrix->m[1][1];
+
+ double i = a*a + c*c;
+ double j = b*b + d*d;
+
+ double f = 0.5 * (i + j);
+ double g = 0.5 * (i - j);
+ double h = a*b + c*d;
+
+ *max = sqrt (f + sqrt (g*g+h*h));
+
+ *min = sqrt (f - sqrt (g*g+h*h));
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
cairo_bool_t
_cairo_matrix_is_integer_translation(cairo_matrix_t *mat,
int *itx, int *ity)
{
double a, b, c, d, tx, ty;
int ttx, tty;
int ok = 0;
cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
Index: cairo_pen.c
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo_pen.c,v
retrieving revision 1.2
diff -u -8 -p -r1.2 cairo_pen.c
--- cairo_pen.c 23 Mar 2005 19:53:39 -0000 1.2
+++ cairo_pen.c 31 Mar 2005 19:53:08 -0000
@@ -367,42 +367,24 @@ doesn't matter where on the circle the e
*/
static int
_cairo_pen_vertices_needed (double tolerance,
double radius,
cairo_matrix_t *matrix)
{
- double a = matrix->m[0][0], c = matrix->m[0][1];
- double b = matrix->m[1][0], d = matrix->m[1][1];
+ double min, max, major_axis;
+ int num_vertices;
- double i = a*a + c*c;
- double j = b*b + d*d;
-
- double f = 0.5 * (i + j);
- double g = 0.5 * (i - j);
- double h = a*b + c*d;
-
- /*
- * compute major and minor axes lengths for
- * a pen with the specified radius
- */
-
- double major_axis = radius * sqrt (f + sqrt (g*g+h*h));
-
- /*
- * we don't need the minor axis length, which is
- * double min = radius * sqrt (f - sqrt (g*g+h*h));
- */
-
+ _cairo_matrix_compute_expansion_factors (matrix, &min, &max);
+ major_axis = radius * max;
/*
* compute number of vertices needed
*/
- int num_vertices;
/* Where tolerance / M is > 1, we use 4 points */
if (tolerance >= major_axis) {
num_vertices = 4;
} else {
double delta = acos (1 - tolerance / major_axis);
num_vertices = ceil (M_PI / delta);
Index: cairoint.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairoint.h,v
retrieving revision 1.4
diff -u -8 -p -r1.4 cairoint.h
--- cairoint.h 29 Mar 2005 20:53:07 -0000 1.4
+++ cairoint.h 31 Mar 2005 19:53:08 -0000
@@ -853,16 +853,18 @@ typedef struct _cairo_gstate {
cairo_line_join_t line_join;
double miter_limit;
cairo_fill_rule_t fill_rule;
double *dash;
int num_dashes;
double dash_offset;
+ double max_dash_length;
+ double fraction_dash_lit;
char *font_family; /* NULL means CAIRO_FONT_FAMILY_DEFAULT; */
cairo_font_slant_t font_slant;
cairo_font_weight_t font_weight;
cairo_font_t *font; /* Specific to the current CTM */
cairo_surface_t *surface;
@@ -1640,16 +1642,19 @@ cairo_private cairo_status_t
_cairo_matrix_compute_determinant (cairo_matrix_t *matrix, double *det);
cairo_private cairo_status_t
_cairo_matrix_compute_eigen_values (cairo_matrix_t *matrix, double *lambda1, double *lambda2);
cairo_private cairo_status_t
_cairo_matrix_compute_scale_factors (cairo_matrix_t *matrix, double *sx, double *sy, int x_major);
+cairo_private cairo_status_t
+_cairo_matrix_compute_expansion_factors (cairo_matrix_t *matrix, double *min, double *max);
+
cairo_private cairo_bool_t
_cairo_matrix_is_integer_translation(cairo_matrix_t *matrix, int *itx, int *ity);
/* cairo_traps.c */
cairo_private void
_cairo_traps_init (cairo_traps_t *traps);
cairo_private void