1 #include <stdlib.h> 2 #include <stdio.h> 3 #include "utils.h" 4 5 static void 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 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 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 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 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 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 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