[cairo-commit] 3 commits - boilerplate/cairo-boilerplate.c configure.in src/cairo-matrix.c src/check-plt.sh test/invalid-matrix.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Jul 5 11:21:19 PDT 2007


 boilerplate/cairo-boilerplate.c |    2 
 configure.in                    |   14 +++++
 src/cairo-matrix.c              |    4 +
 src/check-plt.sh                |    2 
 test/invalid-matrix.c           |   94 ++++++++++++++++++++++++++++++++++------
 5 files changed, 102 insertions(+), 14 deletions(-)

New commits:
diff-tree 5819be398c4eada9a6cfc8e37a532991751b4a51 (from 35ef8419a981929b65157407485ec001b69b3391)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 5 18:59:31 2007 +0100

    [check-plt] Ignore entries for pixman.
    
    pixman is now an external library, so we now expect PLT entries.

diff --git a/src/check-plt.sh b/src/check-plt.sh
index a441b7b..0fdcf74 100755
--- a/src/check-plt.sh
+++ b/src/check-plt.sh
@@ -11,7 +11,7 @@ fi
 
 for so in .libs/lib*.so; do
 	echo Checking $so for local PLT entries
-	readelf -r $so | grep 'JU\?MP_SLO' | grep 'cairo\|pixman' && status=1
+	readelf -r $so | grep 'JU\?MP_SLO' | grep 'cairo' && status=1
 done
 
 exit $status
diff-tree 35ef8419a981929b65157407485ec001b69b3391 (from 7eaba5d5fbf83f66b39db42a89db3e7a892c2ea0)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 5 18:52:21 2007 +0100

    [cairo-matrix] Check determinant for invalid numbers.
    
    By checking matrices for invalid determinants, we can prevent the
    setting and application of invalid matrices.
    
    The trick used here is that NaNs, as specified by IEE754, always
    return FALSE in comparisons. Since we know that the square of the
    determinant must be positive definite, then if the comparison is
    FALSE the computation must have resulted in a NaN.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index c85b027..9e51d04 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -475,6 +475,10 @@ cairo_matrix_invert (cairo_matrix_t *mat
     if (det == 0)
 	return CAIRO_STATUS_INVALID_MATRIX;
 
+    /* this weird construct is for detecting NaNs */
+    if (! (det * det > 0.))
+	return CAIRO_STATUS_INVALID_MATRIX;
+
     _cairo_matrix_compute_adjoint (matrix);
     _cairo_matrix_scalar_multiply (matrix, 1 / det);
 
diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c
index 91140a4..d6b4f50 100644
--- a/test/invalid-matrix.c
+++ b/test/invalid-matrix.c
@@ -45,7 +45,7 @@ draw (cairo_t *cr, int width, int height
     cairo_scaled_font_t *scaled_font;
     cairo_pattern_t *pattern;
     cairo_t *cr2;
-    cairo_matrix_t identity, invalid = {
+    cairo_matrix_t identity, bogus, invalid = {
 	4.0, 4.0,
 	4.0, 4.0,
 	4.0, 4.0
@@ -53,7 +53,7 @@ draw (cairo_t *cr, int width, int height
 
 #define CHECK_STATUS(status, function_name)						\
 if ((status) == CAIRO_STATUS_SUCCESS) {							\
-    cairo_test_log ("Error: %s with invalid matrix passed",				\
+    cairo_test_log ("Error: %s with invalid matrix passed\n",				\
 		    (function_name));							\
     return CAIRO_TEST_FAILURE;								\
 } else if ((status) != CAIRO_STATUS_INVALID_MATRIX) {					\
@@ -64,6 +64,17 @@ if ((status) == CAIRO_STATUS_SUCCESS) {	
 		    cairo_status_to_string (status));					\
 }
 
+    /* create a bogus matrix and check results of attempted inversion */
+    bogus.x0 = bogus.xy = bogus.xx = strtod ("NaN", NULL);
+    bogus.y0 = bogus.yx = bogus.yy = bogus.xx;
+    status = cairo_matrix_invert (&bogus);
+    CHECK_STATUS (status, "cairo_matrix_invert(NaN)");
+
+    /* test cairo_matrix_invert with invalid matrix */
+    status = cairo_matrix_invert (&invalid);
+    CHECK_STATUS (status, "cairo_matrix_invert(invalid)");
+
+
     cairo_matrix_init_identity (&identity);
 
     target = cairo_get_target (cr);
@@ -73,18 +84,34 @@ if ((status) == CAIRO_STATUS_SUCCESS) {	
     cairo_transform (cr2, &invalid);
 
     status = cairo_status (cr2);
-    CHECK_STATUS (status,"cairo_transform");
+    cairo_destroy (cr2);
+    CHECK_STATUS (status, "cairo_transform(invalid)");
 
+    /* test cairo_transform with bogus matrix */
+    cr2 = cairo_create (target);
+    cairo_transform (cr2, &bogus);
+
+    status = cairo_status (cr2);
     cairo_destroy (cr2);
+    CHECK_STATUS (status, "cairo_transform(NaN)");
+
 
     /* test cairo_set_matrix with invalid matrix */
     cr2 = cairo_create (target);
     cairo_set_matrix (cr2, &invalid);
 
     status = cairo_status (cr2);
-    CHECK_STATUS (status, "cairo_set_matrix");
+    cairo_destroy (cr2);
+    CHECK_STATUS (status, "cairo_set_matrix(invalid)");
+
+    /* test cairo_set_matrix with bogus matrix */
+    cr2 = cairo_create (target);
+    cairo_set_matrix (cr2, &bogus);
 
+    status = cairo_status (cr2);
     cairo_destroy (cr2);
+    CHECK_STATUS (status, "cairo_set_matrix(NaN)");
+
 
     /* test cairo_set_font_matrix with invalid matrix */
     cr2 = cairo_create (target);
@@ -94,12 +121,24 @@ if ((status) == CAIRO_STATUS_SUCCESS) {	
     cairo_show_text (cr2, "hello");
 
     status = cairo_status (cr2);
-    CHECK_STATUS (status, "cairo_set_font_matrix");
+    cairo_destroy (cr2);
+    CHECK_STATUS (status, "cairo_set_font_matrix(invalid)");
 
+    /* test cairo_set_font_matrix with bogus matrix */
+    cr2 = cairo_create (target);
+    cairo_set_font_matrix (cr2, &bogus);
+
+    /* draw some text to force the font to be resolved */
+    cairo_show_text (cr2, "hello");
+
+    status = cairo_status (cr2);
     cairo_destroy (cr2);
+    CHECK_STATUS (status, "cairo_set_font_matrix(NaN)");
+
 
     /* test cairo_scaled_font_create with invalid matrix */
-    font_face = cairo_get_font_face (cr);
+    cr2 = cairo_create (target);
+    font_face = cairo_get_font_face (cr2);
     font_options = cairo_font_options_create ();
     cairo_get_font_options (cr, font_options);
     scaled_font = cairo_scaled_font_create (font_face,
@@ -107,7 +146,7 @@ if ((status) == CAIRO_STATUS_SUCCESS) {	
 					    &identity,
 					    font_options);
     status = cairo_scaled_font_status (scaled_font);
-    CHECK_STATUS (status, "cairo_scaled_font_create");
+    CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
 
     cairo_scaled_font_destroy (scaled_font);
 
@@ -116,21 +155,52 @@ if ((status) == CAIRO_STATUS_SUCCESS) {	
 					    &invalid,
 					    font_options);
     status = cairo_scaled_font_status (scaled_font);
-    CHECK_STATUS (status, "cairo_scaled_font_create");
+    CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
 
     cairo_scaled_font_destroy (scaled_font);
     cairo_font_options_destroy (font_options);
+    cairo_destroy (cr2);
+
+    /* test cairo_scaled_font_create with bogus matrix */
+    cr2 = cairo_create (target);
+    font_face = cairo_get_font_face (cr2);
+    font_options = cairo_font_options_create ();
+    cairo_get_font_options (cr, font_options);
+    scaled_font = cairo_scaled_font_create (font_face,
+					    &bogus,
+					    &identity,
+					    font_options);
+    status = cairo_scaled_font_status (scaled_font);
+    CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
+
+    cairo_scaled_font_destroy (scaled_font);
+
+    scaled_font = cairo_scaled_font_create (font_face,
+					    &identity,
+					    &bogus,
+					    font_options);
+    status = cairo_scaled_font_status (scaled_font);
+    CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
+
+    cairo_scaled_font_destroy (scaled_font);
+    cairo_font_options_destroy (font_options);
+    cairo_destroy (cr2);
+
 
     /* test cairo_pattern_set_matrix with invalid matrix */
     pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
     cairo_pattern_set_matrix (pattern, &invalid);
     status = cairo_pattern_status (pattern);
-    CHECK_STATUS (status, "cairo_pattern_set_matrix");
+    CHECK_STATUS (status, "cairo_pattern_set_matrix(invalid)");
+    cairo_pattern_destroy (pattern);
+
+    /* test cairo_pattern_set_matrix with bogus matrix */
+    pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
+    cairo_pattern_set_matrix (pattern, &bogus);
+    status = cairo_pattern_status (pattern);
+    CHECK_STATUS (status, "cairo_pattern_set_matrix(NaN)");
     cairo_pattern_destroy (pattern);
 
-    /* test cairo_matrix_invert with invalid matrix */
-    status = cairo_matrix_invert (&invalid);
-    CHECK_STATUS (status, "cairo_matrix_invert");
 
     return CAIRO_TEST_SUCCESS;
 }
diff-tree 7eaba5d5fbf83f66b39db42a89db3e7a892c2ea0 (from ef967be630dd8d0bf81ad5889d6264bebe7631d4)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 5 15:24:11 2007 +0100

    [configure] Only run PostScript tests if we have ghostscript.
    
    During configure check for the ghostscript command line tool (gs) before
    enabling the PostScript surface tests for make check.

diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 093a55a..7a0f7e8 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -261,7 +261,7 @@ static cairo_boilerplate_target_t target
       _cairo_boilerplate_xlib_cleanup,
       _cairo_boilerplate_xlib_synchronize},
 #endif
-#if CAIRO_HAS_PS_SURFACE
+#if CAIRO_HAS_PS_SURFACE && CAIRO_CAN_TEST_PS_SURFACE
     { "ps", CAIRO_SURFACE_TYPE_PS,
       CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
       _cairo_boilerplate_ps_create_surface,
diff --git a/configure.in b/configure.in
index 6634c22..9fd1942 100644
--- a/configure.in
+++ b/configure.in
@@ -531,6 +531,19 @@ fi
 dnl ===========================================================================
 
 CAIRO_BACKEND_ENABLE(ps, PostScript, ps, PS_SURFACE, auto, [use_ps=yes])
+test_ps=no
+if test "x$use_ps" = "xyes"; then
+  AC_CHECK_PROG(GS, gs, gs)
+  if test "$GS"; then
+    AC_DEFINE([CAIRO_CAN_TEST_PS_SURFACE], 1, [Define to 1 if the PS backend can be tested (needs ghostscript)])
+    test_ps="yes"
+  else
+    AC_MSG_WARN([PS backend will not be tested since ghostscript is not available])
+    test_ps="no (requires ghostscript)"
+  fi
+fi
+
+AM_CONDITIONAL(CAIRO_CAN_TEST_PS_SURFACE, test "x$test_ps" = "xyes")
 
 dnl ===========================================================================
 
@@ -969,6 +982,7 @@ echo ""
 echo "and the following debug options:"
 echo "  gcov support:  $use_gcov"
 echo "  test surfaces: $use_test_surfaces"
+echo "  ps testing:    $test_ps"
 echo "  pdf testing:   $test_pdf"
 echo "  svg testing:   $test_svg"
 echo ""


More information about the cairo-commit mailing list