1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "utils.h"
4
5 static void
make_random_region(pixman_region32_t * region)6 make_random_region (pixman_region32_t *region)
7 {
8 int n_boxes;
9
10 pixman_region32_init (region);
11
12 n_boxes = prng_rand_n (64);
13 while (n_boxes--)
14 {
15 int32_t x, y;
16 uint32_t w, h;
17
18 x = (int32_t)prng_rand() >> 2;
19 y = (int32_t)prng_rand() >> 2;
20 w = prng_rand() >> 2;
21 h = prng_rand() >> 2;
22
23 pixman_region32_union_rect (region, region, x, y, w, h);
24 }
25 }
26
27 static void
print_box(pixman_box32_t * box)28 print_box (pixman_box32_t *box)
29 {
30 printf (" %d %d %d %d\n", box->x1, box->y1, box->x2, box->y2);
31 }
32
33 static int32_t
random_coord(pixman_region32_t * region,pixman_bool_t x)34 random_coord (pixman_region32_t *region, pixman_bool_t x)
35 {
36 pixman_box32_t *b, *bb;
37 int n_boxes;
38 int begin, end;
39
40 if (prng_rand_n (14))
41 {
42 bb = pixman_region32_rectangles (region, &n_boxes);
43 if (n_boxes == 0)
44 goto use_extent;
45 b = bb + prng_rand_n (n_boxes);
46 }
47 else
48 {
49 use_extent:
50 b = pixman_region32_extents (region);
51 n_boxes = 1;
52 }
53
54 if (x)
55 {
56 begin = b->x1;
57 end = b->x2;
58 }
59 else
60 {
61 begin = b->y1;
62 end = b->y2;
63 }
64
65 switch (prng_rand_n (5))
66 {
67 case 0:
68 return begin - prng_rand();
69 case 1:
70 return end + prng_rand ();
71 case 2:
72 return end;
73 case 3:
74 return begin;
75 default:
76 return (end - begin) / 2 + begin;
77 }
78 return 0;
79 }
80
81 static uint32_t
compute_crc32_u32(uint32_t crc32,uint32_t v)82 compute_crc32_u32 (uint32_t crc32, uint32_t v)
83 {
84 if (!is_little_endian())
85 {
86 v = ((v & 0xff000000) >> 24) |
87 ((v & 0x00ff0000) >> 8) |
88 ((v & 0x0000ff00) << 8) |
89 ((v & 0x000000ff) << 24);
90 }
91
92 return compute_crc32 (crc32, &v, sizeof (int32_t));
93 }
94
95 static uint32_t
crc32_box32(uint32_t crc32,pixman_box32_t * box)96 crc32_box32 (uint32_t crc32, pixman_box32_t *box)
97 {
98 crc32 = compute_crc32_u32 (crc32, box->x1);
99 crc32 = compute_crc32_u32 (crc32, box->y1);
100 crc32 = compute_crc32_u32 (crc32, box->x2);
101 crc32 = compute_crc32_u32 (crc32, box->y2);
102
103 return crc32;
104 }
105
106 static uint32_t
test_region_contains_rectangle(int i,int verbose)107 test_region_contains_rectangle (int i, int verbose)
108 {
109 pixman_box32_t box;
110 pixman_box32_t rbox = { 0, 0, 0, 0 };
111 pixman_region32_t region;
112 uint32_t r, r1, r2, r3, r4, crc32;
113
114 prng_srand (i);
115
116 make_random_region (®ion);
117
118 box.x1 = random_coord (®ion, TRUE);
119 box.x2 = box.x1 + prng_rand ();
120 box.y1 = random_coord (®ion, FALSE);
121 box.y2 = box.y1 + prng_rand ();
122
123 if (verbose)
124 {
125 int n_rects;
126 pixman_box32_t *boxes;
127
128 boxes = pixman_region32_rectangles (®ion, &n_rects);
129
130 printf ("region:\n");
131 while (n_rects--)
132 print_box (boxes++);
133 printf ("box:\n");
134 print_box (&box);
135 }
136
137 crc32 = 0;
138
139 r1 = pixman_region32_contains_point (®ion, box.x1, box.y1, &rbox);
140 crc32 = crc32_box32 (crc32, &rbox);
141 r2 = pixman_region32_contains_point (®ion, box.x1, box.y2, &rbox);
142 crc32 = crc32_box32 (crc32, &rbox);
143 r3 = pixman_region32_contains_point (®ion, box.x2, box.y1, &rbox);
144 crc32 = crc32_box32 (crc32, &rbox);
145 r4 = pixman_region32_contains_point (®ion, box.x2, box.y2, &rbox);
146 crc32 = crc32_box32 (crc32, &rbox);
147
148 r = pixman_region32_contains_rectangle (®ion, &box);
149 r = (i << 8) | (r << 4) | (r1 << 3) | (r2 << 2) | (r3 << 1) | (r4 << 0);
150
151 crc32 = compute_crc32_u32 (crc32, r);
152
153 if (verbose)
154 printf ("results: %d %d %d %d %d\n", (r & 0xf0) >> 4, r1, r2, r3, r4);
155
156 pixman_region32_fini (®ion);
157
158 return crc32;
159 }
160
161 int
main(int argc,const char * argv[])162 main (int argc, const char *argv[])
163 {
164 return fuzzer_test_main ("region_contains",
165 1000000,
166 0x548E0F3F,
167 test_region_contains_rectangle,
168 argc, argv);
169 }
170