summaryrefslogtreecommitdiff
path: root/test/radial-invalid.c
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2014-04-23 20:07:37 -0400
committerSøren Sandmann <ssp@redhat.com>2014-05-15 13:29:38 -0400
commitf5f5dbbbc668a3a90c6cfc79bbd2422805db31e7 (patch)
treeaac9a5c273f3483042b2a3bf210e165215f3f19e /test/radial-invalid.c
parent91f32ce961bc85f98b3372b95681ad8918d24b18 (diff)
downloadpixman-f5f5dbbbc668a3a90c6cfc79bbd2422805db31e7.tar.gz
test: Add radial-invalid test program
This program demonstrates a bug in gradient walker, where some integer overflows cause colors outside the range [0, 255] to be generated, which in turns cause 'invalid' floating point exceptions when those colors are converted to uint8_t. The bug was first reported by Owen Taylor on the #cairo IRC channel.
Diffstat (limited to 'test/radial-invalid.c')
-rw-r--r--test/radial-invalid.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/test/radial-invalid.c b/test/radial-invalid.c
new file mode 100644
index 0000000..ec85fe3
--- /dev/null
+++ b/test/radial-invalid.c
@@ -0,0 +1,54 @@
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+
+#define WIDTH 100
+#define HEIGHT 100
+
+int
+main ()
+{
+ pixman_image_t *radial;
+ pixman_image_t *dest = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, WIDTH, HEIGHT, NULL, -1);
+
+ static const pixman_transform_t xform =
+ {
+ { { 0x346f7, 0x0, 0x0 },
+ { 0x0, 0x346f7, 0x0 },
+ { 0x0, 0x0, 0x10000 }
+ },
+ };
+
+ static const pixman_gradient_stop_t stops[] =
+ {
+ { 0xde61, { 0x4481, 0x96e8, 0x1e6a, 0x29e1 } },
+ { 0xfdd5, { 0xfa10, 0xcc26, 0xbc43, 0x1eb7 } },
+ { 0xfe1e, { 0xd257, 0x5bac, 0x6fc2, 0xa33b } },
+ };
+
+ static const pixman_point_fixed_t inner = { 0x320000, 0x320000 };
+ static const pixman_point_fixed_t outer = { 0x320000, 0x3cb074 };
+
+ enable_divbyzero_exceptions ();
+ enable_invalid_exceptions ();
+
+ radial = pixman_image_create_radial_gradient (
+ &inner,
+ &outer,
+ 0xab074, /* inner radius */
+ 0x0, /* outer radius */
+ stops, sizeof (stops) / sizeof (stops[0]));
+
+ pixman_image_set_repeat (radial, PIXMAN_REPEAT_REFLECT);
+ pixman_image_set_transform (radial, &xform);
+
+ pixman_image_composite (
+ PIXMAN_OP_OVER,
+ radial, NULL, dest,
+ 0, 0, 0, 0,
+ 0, 0, WIDTH, HEIGHT);
+
+ return 0;
+}