[cairo-commit] 2 commits - src/cairo.h src/cairo-surface.c
test/cairo-test.c test/cairo-test.h
Behdad Esfahbod
behdad at kemper.freedesktop.org
Fri Jun 30 17:07:00 PDT 2006
src/cairo-surface.c | 30 ++++++++++++++++++++++++++
src/cairo.h | 5 ++--
test/cairo-test.c | 59 ++++++++++++++++++++++++++++++++++++++++------------
test/cairo-test.h | 3 +-
4 files changed, 81 insertions(+), 16 deletions(-)
New commits:
diff-tree cfddf93afb692819548adb85c5b75f60be7e7349 (from 01b1f3572c3c15a08dd6f32788106c0e42fd2436)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 1 01:55:12 2006 +0200
Make CAIRO_EXTEND_REFLECT and CAIRO_EXTEND_PAD not crash on surface patterns,
but return error.
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index dd349c2..66f7a46 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1178,6 +1178,12 @@ _cairo_surface_paint (cairo_surface_t *s
assert (! surface->is_snapshot);
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD))
+ {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
if (surface->backend->paint) {
@@ -1206,6 +1212,12 @@ _cairo_surface_mask (cairo_surface_t *su
assert (! surface->is_snapshot);
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD))
+ {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
_cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
@@ -1244,6 +1256,12 @@ _cairo_surface_stroke (cairo_surface_t
assert (! surface->is_snapshot);
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD))
+ {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
if (surface->backend->stroke) {
@@ -1283,6 +1301,12 @@ _cairo_surface_fill (cairo_surface_t *su
assert (! surface->is_snapshot);
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD))
+ {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
if (surface->backend->fill) {
@@ -1684,6 +1708,12 @@ _cairo_surface_show_glyphs (cairo_surfac
assert (! surface->is_snapshot);
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD))
+ {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
_cairo_surface_copy_pattern_for_destination (source,
surface,
&dev_source.base);
diff --git a/src/cairo.h b/src/cairo.h
index d2116cb..ab860e8 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -1492,9 +1492,10 @@ cairo_pattern_get_matrix (cairo_pattern_
* are fully transparent
* @CAIRO_EXTEND_REPEAT: the pattern is tiled by repeating
* @CAIRO_EXTEND_REFLECT: the pattern is tiled by reflecting
- * at the edges
+ * at the edges (not implemented for surface patterns currently)
* @CAIRO_EXTEND_PAD: pixels outside of the pattern copy
- * the closest pixel from the source (Since 1.2)
+ * the closest pixel from the source (Since 1.2; not implemented
+ * for surface patterns currently)
*
* #cairo_extend_t is used to describe how the area outside
* of a pattern will be drawn.
diff-tree 01b1f3572c3c15a08dd6f32788106c0e42fd2436 (from 19c4700101bfce7d73a50017021b4ec198ddd783)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jun 30 22:01:24 2006 +0200
Detect and report crashes in tests.
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 651b9f0..38acd0d 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -31,6 +31,8 @@
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
+#include <setjmp.h>
+#include <signal.h>
#include <assert.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -68,6 +70,12 @@ typedef enum cairo_internal_surface_type
#define access _access
#define F_OK 0
#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
static void
xunlink (const char *pathname);
@@ -89,6 +97,12 @@ static const char *fail_face = "", *norm
* general-purpose library, and it keeps the tests cleaner to avoid a
* context object there, (though not a whole lot). */
FILE *cairo_test_log_file = NULL;
+char *srcdir;
+
+/* Used to catch crashes in a test, such that we report it as such and
+ * continue testing, although one crasher may already have corrupted memory in
+ * an nonrecoverable fashion. */
+jmp_buf jmpbuf;
void
cairo_test_init (const char *test_name)
@@ -1463,15 +1477,11 @@ cairo_test_for_target (cairo_test_t *tes
cairo_surface_t *surface;
cairo_t *cr;
char *png_name, *ref_name, *diff_name, *offset_str;
- char *srcdir;
char *format;
cairo_test_status_t ret;
cairo_content_t expected_content;
/* Get the strings ready that we'll need. */
- srcdir = getenv ("srcdir");
- if (!srcdir)
- srcdir = ".";
format = _cairo_test_content_name (target->content);
if (dev_offset)
@@ -1613,12 +1623,19 @@ UNWIND_STRINGS:
return ret;
}
+static void
+segfault_handler (int signal)
+{
+ longjmp (jmpbuf, signal);
+}
+
static cairo_test_status_t
cairo_test_expecting (cairo_test_t *test, cairo_test_draw_function_t draw,
cairo_test_status_t expectation)
{
- int i, j, num_targets;
+ volatile int i, j, num_targets;
const char *tname;
+ sighandler_t old_segfault_handler;
cairo_test_status_t status, ret;
cairo_test_target_t **targets_to_test;
cairo_test_target_t targets[] =
@@ -1751,6 +1768,17 @@ cairo_test_expecting (cairo_test_t *test
#endif
};
+#ifdef HAVE_UNISTD_H
+ if (isatty (1)) {
+ fail_face = "\033[41m\033[37m\033[1m";
+ normal_face = "\033[m";
+ }
+#endif
+
+ srcdir = getenv ("srcdir");
+ if (!srcdir)
+ srcdir = ".";
+
if ((tname = getenv ("CAIRO_TEST_TARGET")) != NULL) {
const char *tname = getenv ("CAIRO_TEST_TARGET");
num_targets = 0;
@@ -1794,7 +1822,7 @@ cairo_test_expecting (cairo_test_t *test
* iff. there is at least one tested backend and that all tested
* backends return SUCCESS. In other words:
*
- * if any backend FAILURE
+ * if any backend not SUCCESS
* -> FAILURE
* else if all backends UNTESTED
* -> FAILURE
@@ -1812,7 +1840,13 @@ cairo_test_expecting (cairo_test_t *test
_cairo_test_content_name (target->content),
dev_offset);
- status = cairo_test_for_target (test, draw, target, dev_offset);
+ /* Set up a checkpoint to get back to in case of segfaults. */
+ old_segfault_handler = signal (SIGSEGV, (sighandler_t) segfault_handler);
+ if (0 == setjmp (jmpbuf))
+ status = cairo_test_for_target (test, draw, target, dev_offset);
+ else
+ status = CAIRO_TEST_CRASHED;
+ signal (SIGSEGV, (sighandler_t) old_segfault_handler);
cairo_test_log ("TEST: %s TARGET: %s FORMAT: %s OFFSET: %d RESULT: ",
test->name, target->name,
@@ -1830,6 +1864,11 @@ cairo_test_expecting (cairo_test_t *test
printf ("UNTESTED\n");
cairo_test_log ("UNTESTED\n");
break;
+ case CAIRO_TEST_CRASHED:
+ printf ("%s!!!CRASHED!!!%s\n", fail_face, normal_face);
+ cairo_test_log ("CRASHED\n");
+ ret = CAIRO_TEST_FAILURE;
+ break;
default:
case CAIRO_TEST_FAILURE:
if (expectation == CAIRO_TEST_FAILURE) {
@@ -1870,12 +1909,6 @@ cairo_test_expect_failure (cairo_test_t
cairo_test_status_t
cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw)
{
-#ifdef HAVE_UNISTD_H
- if (isatty (1)) {
- fail_face = "\033[41m\033[37m\033[1m";
- normal_face = "\033[m";
- }
-#endif
printf ("\n");
return cairo_test_expecting (test, draw, CAIRO_TEST_SUCCESS);
}
diff --git a/test/cairo-test.h b/test/cairo-test.h
index d47c47f..f33ea1e 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -67,7 +67,8 @@ typedef unsigned __int64 uint64_t;
typedef enum cairo_test_status {
CAIRO_TEST_SUCCESS = 0,
CAIRO_TEST_FAILURE,
- CAIRO_TEST_UNTESTED
+ CAIRO_TEST_UNTESTED,
+ CAIRO_TEST_CRASHED
} cairo_test_status_t;
typedef struct cairo_test {
More information about the cairo-commit
mailing list