test: 'scaling-crash-test' added
authorSiarhei Siamashka <siarhei.siamashka@nokia.com>
Mon, 19 Jul 2010 17:25:05 +0000 (20:25 +0300)
committerSiarhei Siamashka <siarhei.siamashka@nokia.com>
Tue, 27 Jul 2010 13:07:07 +0000 (16:07 +0300)
This test tries to exploit some corner cases and previously known
bugs in nearest neighbor scaling fast path code, attempting to
crash pixman or cause some other nasty effect.

test/Makefile.am
test/scaling-crash-test.c [new file with mode: 0644]

index 20cb00f..2a7aea2 100644 (file)
@@ -13,6 +13,7 @@ TESTPROGRAMS =                        \
        gradient-crash-test     \
        trap-crasher            \
        alphamap                \
+       scaling-crash-test      \
        blitters-test           \
        scaling-test            \
        composite
@@ -24,6 +25,7 @@ gradient_crash_test_LDADD = $(TEST_LDADD)
 trap_crasher_LDADD = $(TEST_LDADD)
 oob_test_LDADD = $(TEST_LDADD)
 window_test_LDADD = $(TEST_LDADD)
+scaling_crash_test_LDADD = $(TEST_LDADD)
 
 region_test_LDADD = $(TEST_LDADD)
 region_test_SOURCES = region-test.c utils.c utils.h
diff --git a/test/scaling-crash-test.c b/test/scaling-crash-test.c
new file mode 100644 (file)
index 0000000..4ab01e3
--- /dev/null
@@ -0,0 +1,124 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "pixman.h"
+
+/*
+ * We have a source image filled with solid color, set NORMAL or PAD repeat,
+ * and some transform which results in nearest neighbour scaling.
+ *
+ * The expected result is the destination image filled with this solid
+ * color.
+ */
+static int
+do_test (int32_t               dst_size,
+        int32_t                src_size,
+        int32_t                src_offs,
+        int32_t                scale_factor,
+        pixman_repeat_t        repeat)
+{
+    int i;
+    pixman_image_t *   src_img;
+    pixman_image_t *   dst_img;
+    pixman_transform_t transform;
+    uint32_t *         srcbuf;
+    uint32_t *         dstbuf;
+
+    srcbuf = (uint32_t *)malloc (src_size * 4);
+    dstbuf = (uint32_t *)malloc (dst_size * 4);
+
+    /* horizontal test */
+    memset (srcbuf, 0xCC, src_size * 4);
+    memset (dstbuf, 0x33, dst_size * 4);
+
+    src_img = pixman_image_create_bits (
+        PIXMAN_a8r8g8b8, src_size, 1, srcbuf, src_size * 4);
+    dst_img = pixman_image_create_bits (
+        PIXMAN_a8r8g8b8, dst_size, 1, dstbuf, dst_size * 4);
+
+    pixman_transform_init_scale (&transform, scale_factor, 65536);
+    pixman_image_set_transform (src_img, &transform);
+    pixman_image_set_repeat (src_img, repeat);
+    pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
+
+    pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
+                            src_offs, 0, 0, 0, 0, 0, dst_size, 1);
+
+    pixman_image_unref (src_img);
+    pixman_image_unref (dst_img);
+
+    for (i = 0; i < dst_size; i++)
+    {
+       if (dstbuf[i] != 0xCCCCCCCC)
+       {
+           free (srcbuf);
+           free (dstbuf);
+           return 1;
+       }
+    }
+
+    /* vertical test */
+    memset (srcbuf, 0xCC, src_size * 4);
+    memset (dstbuf, 0x33, dst_size * 4);
+
+    src_img = pixman_image_create_bits (
+        PIXMAN_a8r8g8b8, 1, src_size, srcbuf, 4);
+    dst_img = pixman_image_create_bits (
+        PIXMAN_a8r8g8b8, 1, dst_size, dstbuf, 4);
+
+    pixman_transform_init_scale (&transform, 65536, scale_factor);
+    pixman_image_set_transform (src_img, &transform);
+    pixman_image_set_repeat (src_img, repeat);
+    pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
+
+    pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
+                            0, src_offs, 0, 0, 0, 0, 1, dst_size);
+
+    pixman_image_unref (src_img);
+    pixman_image_unref (dst_img);
+
+    for (i = 0; i < dst_size; i++)
+    {
+       if (dstbuf[i] != 0xCCCCCCCC)
+       {
+           free (srcbuf);
+           free (dstbuf);
+           return 1;
+       }
+    }
+
+    free (srcbuf);
+    free (dstbuf);
+    return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+    pixman_disable_out_of_bounds_workaround ();
+
+    /* can potentially crash */
+    assert (do_test (
+       48000, 32767, 1, 65536 * 128, PIXMAN_REPEAT_NORMAL) == 0);
+
+    /* can potentially get into a deadloop */
+    assert (do_test (
+       16384, 65536, 32, 32768, PIXMAN_REPEAT_NORMAL) == 0);
+
+#if 0
+    /* can potentially access memory outside source image buffer */
+    assert (do_test (
+       10, 10, 0, 1, PIXMAN_REPEAT_PAD) == 0);
+    assert (do_test (
+       10, 10, 0, 0, PIXMAN_REPEAT_PAD) == 0);
+#endif
+
+#if 0
+    /* can potentially provide invalid results (out of range matrix stuff) */
+    assert (do_test (
+       48000, 32767, 16384, 65536 * 128, PIXMAN_REPEAT_NORMAL) == 0);
+#endif
+
+    return 0;
+}