summaryrefslogtreecommitdiff
path: root/test/invalid-matrix.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2007-07-05 18:52:21 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2007-07-05 19:15:07 +0100
commit35ef8419a981929b65157407485ec001b69b3391 (patch)
treef4f0ec173d20f4051dd97e1ee492aa862e1c5aea /test/invalid-matrix.c
parent7eaba5d5fbf83f66b39db42a89db3e7a892c2ea0 (diff)
downloadcairo-35ef8419a981929b65157407485ec001b69b3391.tar.gz
[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.
Diffstat (limited to 'test/invalid-matrix.c')
-rw-r--r--test/invalid-matrix.c94
1 files changed, 82 insertions, 12 deletions
diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c
index 91140a403..d6b4f5044 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;
}