bgo#776932: Don't render nodes whose "transform" attribute is invalid

In the SVG 1.1 test suite, coords-trans-09-t.svg comes with this transform:

    <g transform="matrix(0 0 0 0 0 0)">

which is invalid.  Now we detect whether transforms are in fact invalid,
and propagate this info so that the corresponding nodes are not rendered.

https://bugzilla.gnome.org/show_bug.cgi?id=776932
parent edd363a0
......@@ -25,6 +25,7 @@
*/
#include "config.h"
#include <errno.h>
#include <string.h>
#include <math.h>
......@@ -1305,16 +1306,18 @@ ccss_import_style (CRDocHandler * a_this,
working draft dated 1999-07-06, section 8.5. Return TRUE on
success. */
gboolean
rsvg_parse_transform (cairo_matrix_t *dst, const char *src)
rsvg_parse_transform (cairo_matrix_t *out_matrix, const char *src)
{
cairo_matrix_t dst;
int idx;
char keyword[32];
double args[6];
int n_args;
guint key_len;
cairo_matrix_t affine;
cairo_matrix_t inverse;
cairo_matrix_init_identity (dst);
cairo_matrix_init_identity (&dst);
idx = 0;
while (src[idx]) {
......@@ -1358,7 +1361,11 @@ rsvg_parse_transform (cairo_matrix_t *dst, const char *src)
if (g_ascii_isdigit (c) || c == '+' || c == '-' || c == '.') {
if (n_args == sizeof (args) / sizeof (args[0]))
return FALSE; /* too many args */
args[n_args] = g_ascii_strtod (src + idx, &end_ptr);
if (errno == ERANGE)
return FALSE; /* overflow / underflow */
idx = end_ptr - src;
while (g_ascii_isspace (src[idx]))
......@@ -1380,42 +1387,42 @@ rsvg_parse_transform (cairo_matrix_t *dst, const char *src)
return FALSE;
cairo_matrix_init (&affine, args[0], args[1], args[2], args[3], args[4], args[5]);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else if (!strcmp (keyword, "translate")) {
if (n_args == 1)
args[1] = 0;
else if (n_args != 2)
return FALSE;
cairo_matrix_init_translate (&affine, args[0], args[1]);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else if (!strcmp (keyword, "scale")) {
if (n_args == 1)
args[1] = args[0];
else if (n_args != 2)
return FALSE;
cairo_matrix_init_scale (&affine, args[0], args[1]);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else if (!strcmp (keyword, "rotate")) {
if (n_args == 1) {
cairo_matrix_init_rotate (&affine, args[0] * M_PI / 180.);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else if (n_args == 3) {
cairo_matrix_init_translate (&affine, args[1], args[2]);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
cairo_matrix_init_rotate (&affine, args[0] * M_PI / 180.);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
cairo_matrix_init_translate (&affine, -args[1], -args[2]);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else
return FALSE;
} else if (!strcmp (keyword, "skewX")) {
if (n_args != 1)
return FALSE;
_rsvg_cairo_matrix_init_shear (&affine, args[0]);
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else if (!strcmp (keyword, "skewY")) {
if (n_args != 1)
return FALSE;
......@@ -1423,10 +1430,17 @@ rsvg_parse_transform (cairo_matrix_t *dst, const char *src)
/* transpose the affine, given that we know [1] is zero */
affine.yx = affine.xy;
affine.xy = 0.;
cairo_matrix_multiply (dst, &affine, dst);
cairo_matrix_multiply (&dst, &affine, &dst);
} else
return FALSE; /* unknown keyword */
}
inverse = dst;
if (cairo_matrix_invert (&inverse) != CAIRO_STATUS_SUCCESS) {
return FALSE; /* we got passed an invalid matrix */
}
*out_matrix = dst;
return TRUE;
}
......
<svg version="1.1" baseProfile="tiny" id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!--======================================================================-->
<!--= SVG 1.1 2nd Edition Test Case =-->
<!--======================================================================-->
<!--= Copyright 2009 World Wide Web Consortium, (Massachusetts =-->
<!--= Institute of Technology, European Research Consortium for =-->
<!--= Informatics and Mathematics (ERCIM), Keio University). =-->
<!--= All Rights Reserved. =-->
<!--= See http://www.w3.org/Consortium/Legal/. =-->
<!--======================================================================-->
<d:SVGTestCase xmlns:d="http://www.w3.org/2000/02/svg/testsuite/description/"
template-version="1.4" reviewer="OA" author="CN" status="accepted"
version="$Revision: 1.6 $" testname="$RCSfile: coords-trans-09-t.svg,v $">
<d:testDescription xmlns="http://www.w3.org/1999/xhtml" href="http://www.w3.org/TR/SVG11/coords.html#EstablishingANewUserSpace">
<p>
This test verifies the implementation of transforms. It tests elementary transforms
and transform nesting.
Note that for layout purposes, this test uses nesting of translation with the elementary transforms.
</p>
<p>
This test will check if the various matrix operations work
</p>
</d:testDescription>
<d:operatorScript xmlns="http://www.w3.org/1999/xhtml">
<p>
Run the test. No interaction required.
</p>
</d:operatorScript>
<d:passCriteria xmlns="http://www.w3.org/1999/xhtml">
<p>
The rendered picture should match the reference image exactly except for variations in the labeling text.
</p>
</d:passCriteria>
</d:SVGTestCase>
<title id="test-title">$RCSfile: coords-trans-09-t.svg,v $</title>
<defs>
<font-face font-family="SVGFreeSansASCII" unicode-range="U+0-7F">
<font-face-src>
<font-face-uri xlink:href="../resources/SVGFreeSans.svg#ascii"/>
</font-face-src>
</font-face>
</defs>
<g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
<g id="elementary-transforms-test">
<g transform="matrix(0 0 0 0 0 0)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="6" y="20" font-size="20">matrix(0 0 0 0 0 0)</text>
<g transform="matrix(1 0 0 1 100 100)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="100" y="100" font-size="20">matrix(1 0 0 1 100 100)</text>
<g transform="matrix(1.5 0 0 1.5 70 60)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="70" y="60" font-size="20">matrix(1.5 0 0 1.5 70 60)</text>
<g transform="matrix(1 0 0.5 1 30 170)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="30" y="170" font-size="20">matrix(1 0 0.5 1 30 170)</text>
<g transform="matrix(1 0.5 0 1 100 200)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="100" y="200" font-size="20">matrix(1 0.5 0 1 100 200)</text>
<g transform="matrix(0 1 -1 0 450 0)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="275" y="30" font-size="20">matrix(0 1 -1 0 450 0)</text>
<g transform="matrix(1 0.8 0.8 1 300 220)">
<rect x="0" y="0" width="150" height="5" fill="blue"/>
<rect x="0" y="0" width="5" height="50" fill="red"/>
</g>
<text x="230" y="220" font-size="20">matrix(1 0.8 0.8 1 300 220)</text>
</g>
</g>
<g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
<text id="revision" x="10" y="340" stroke="none" fill="black">$Revision: 1.6 $</text>
</g>
<rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
<!-- comment out this watermark once the test is approved -->
<!--<g id="draft-watermark">
<rect x="1" y="1" width="478" height="20" fill="red" stroke="black" stroke-width="1"/>
<text font-family="SVGFreeSansASCII,sans-serif" font-weight="bold" font-size="20" x="240"
text-anchor="middle" y="18" stroke-width="0.5" stroke="black" fill="white">DRAFT</text>
</g>-->
</svg>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment