Bug Summary

File:main.c
Location:line 218, column 23
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/*
2 * Copyright © 2004 Eric Anholt
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Eric Anholt not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Eric Anholt makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include "rendercheck.h"
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include <strings.h>
28#include <getopt.h>
29
30extern int num_ops;
31extern int num_colors;
32
33Boolint is_verbose = FALSE0, minimalrendering = FALSE0;
34int enabled_tests = ~0; /* Enable all tests by default */
35
36int format_whitelist_len = 0;
37char **format_whitelist;
38
39/* Number of times to repeat operations so that pixmaps will tend to get moved
40 * into offscreen memory and allow hardware acceleration.
41 */
42int pixmap_move_iter = 1;
43
44int win_width = 40;
45int win_height = 200;
46
47int
48bit_count(int i)
49{
50 int count;
51
52 count = (i >> 1) & 033333333333;
53 count = i - count - ((count >> 1) & 033333333333);
54 count = (((count + (count >> 3)) & 030707070707) % 077);
55 /* HAKMEM 169 */
56 return count;
57}
58
59/* This is not complete, but decent enough for now.*/
60void
61describe_format(char *desc, int len, XRenderPictFormat *format)
62{
63 char ad[4] = "", rd[4] = "", gd[4] = "", bd[4] = "";
64 int ac, rc, gc, bc;
65 int ashift;
66
67 ac = bit_count(format->direct.alphaMask);
68 rc = bit_count(format->direct.redMask);
69 gc = bit_count(format->direct.greenMask);
70 bc = bit_count(format->direct.blueMask);
71
72 if (ac != 0) {
73 snprintf(ad, 4, "a%d", ac);
74 ashift = format->direct.alpha;
75 } else if (rc + bc + gc < format->depth) {
76 /* There are bits that are not part of A,R,G,B. Mark them with
77 * an x.
78 */
79 snprintf(ad, 4, "x%d", format->depth - rc - gc - bc);
80 if (format->direct.red == 0 || format->direct.blue == 0)
81 ashift = format->depth;
82 else
83 ashift = 0;
84 } else
85 ashift = 0;
86
87 if (rc != 0)
88 snprintf(rd, 4, "r%d", rc);
89 if (gc != 0)
90 snprintf(gd, 4, "g%d", gc);
91 if (bc != 0)
92 snprintf(bd, 4, "b%d", bc);
93
94 if (ashift > format->direct.red) {
95 if (format->direct.red > format->direct.blue)
96 snprintf(desc, len, "%s%s%s%s", ad, rd, gd, bd);
97 else
98 snprintf(desc, len, "%s%s%s%s", ad, bd, gd, rd);
99 } else {
100 if (format->direct.red > format->direct.blue)
101 snprintf(desc, len, "%s%s%s%s", rd, gd, bd, ad);
102 else
103 snprintf(desc, len, "%s%s%s%s", bd, gd, rd, ad);
104 }
105}
106
107struct {
108 int flag;
109 const char *name;
110} available_tests[] = {
111 {TEST_FILL0x0001, "fill"},
112 {TEST_DSTCOORDS0x0002, "dcoords"},
113 {TEST_SRCCOORDS0x0004, "scoords"},
114 {TEST_MASKCOORDS0x0008, "mcoords"},
115 {TEST_TSRCCOORDS0x0010, "tscoords"},
116 {TEST_TMASKCOORDS0x0020, "tmcoords"},
117 {TEST_BLEND0x0040, "blend"},
118 {TEST_COMPOSITE0x0080, "composite"},
119 {TEST_CACOMPOSITE0x0100, "cacomposite"},
120 {TEST_GRADIENTS0x0200, "gradients"},
121 {TEST_REPEAT0x0400, "repeat"},
122 {TEST_TRIANGLES0x0800, "triangles"},
123 {TEST_BUG73660x1000, "bug7366"},
124 {0, NULL((void*)0)}
125};
126
127void print_tests(FILE *file, int tests) {
128 int i, j;
129
130 for (i=0, j=0; available_tests[i].name; i++) {
131 if (!(available_tests[i].flag & tests))
132 continue;
133 if (j % 5 == 0) {
134 if(j != 0)
135 putc('\n', stderr)_IO_putc ('\n', stderr);
136 putc('\t', stderr)_IO_putc ('\t', stderr);
137 } else {
138 fprintf(stderrstderr, ", ");
139 }
140 fprintf(stderrstderr, "%s", available_tests[i].name);
141 j++;
142 }
143 if (j)
144 fprintf(file, "\n");
145}
146
147_X_NORETURN__attribute((noreturn))
148static void
149usage (char *program)
150{
151 fprintf(stderrstderr, "usage: %s [-d|--display display] [-v|--verbose]\n"
152 "\t[-t test1,test2,...] [-o op1,op2,...] [-f format1,format2,...]\n"
153 "\t[--sync] [--minimalrendering] [--version]\n"
154 "Available tests:\n", program);
155 print_tests(stderrstderr, ~0);
156 exit(1);
157}
158
159int main(int argc, char **argv)
160{
161 Display *dpy;
162 XEvent ev;
163 int i, o, maj, min;
164 static Boolint is_sync = FALSE0, print_version = FALSE0;
165 XWindowAttributes a;
166 XSetWindowAttributes as;
167 picture_info window;
168 char *display = NULL((void*)0);
169 char *test, *format, *opname, *nextname;
170
171 static struct option longopts[] = {
172 { "display", required_argument1, NULL((void*)0), 'd' },
173 { "iterations", required_argument1, NULL((void*)0), 'i' },
174 { "formats", required_argument1, NULL((void*)0), 'f' },
175 { "tests", required_argument1, NULL((void*)0), 't' },
176 { "ops", required_argument1, NULL((void*)0), 'o' },
177 { "verbose", no_argument0, NULL((void*)0), 'v' },
178 { "sync", no_argument0, &is_sync, TRUE1},
179 { "minimalrendering", no_argument0, &minimalrendering,
180 TRUE1},
181 { "version", no_argument0, &print_version, TRUE1 },
182 { NULL((void*)0), 0, NULL((void*)0), 0 }
183 };
184
185 while ((o = getopt_long(argc, argv, "d:i:f:t:o:v", longopts, NULL((void*)0))) != -1) {
1
Loop condition is true. Entering loop body
4
Loop condition is true. Entering loop body
7
Loop condition is true. Entering loop body
186 switch (o) {
2
Control jumps to 'case 0:' at line 255
5
Control jumps to 'case 0:' at line 255
8
Control jumps to 'case 102:' at line 210
187 case 'd':
188 display = optarg;
189 break;
190 case 'i':
191 pixmap_move_iter = atoi(optarg);
192 break;
193 case 'o':
194 for (i = 0; i < num_ops; i++)
195 ops[i].disabled = TRUE1;
196
197 nextname = optarg;
198 while ((opname = strsep(&nextname, ",")) != NULL((void*)0)) {
199 for (i = 0; i < num_ops; i++) {
200 if (strcasecmp(ops[i].name, opname) !=
201 0)
202 continue;
203 ops[i].disabled = FALSE0;
204 break;
205 }
206 if (i == num_ops)
207 usage(argv[0]);
208 }
209 break;
210 case 'f':
211 nextname = optarg;
212 for (format_whitelist_len = 0;;format_whitelist_len++)
9
Loop condition is true. Entering loop body
213 {
214 if ((format = strsep(&nextname, ",")) == NULL((void*)0))
10
Taking true branch
215 break;
11
Execution continues on line 218
216 }
217
218 format_whitelist = malloc(sizeof(char *) *
12
Call to 'malloc' has an allocation size of 0 bytes
219 format_whitelist_len);
220 if (format_whitelist == NULL((void*)0))
221 errx(1, "malloc");
222
223 /* Now the list is separated by \0s, so use strlen to
224 * step between entries.
225 */
226 format = optarg;
227 for (i = 0; i < format_whitelist_len; i++) {
228 format_whitelist[i] = strdup(format);
229 format += strlen(format) + 1;
230 }
231
232 break;
233 case 't':
234 nextname = optarg;
235
236 /* disable all tests */
237 enabled_tests = 0;
238
239 while ((test = strsep(&nextname, ",")) != NULL((void*)0)) {
240 int i;
241 for(i=0; available_tests[i].name; i++) {
242 if(strcmp(test, available_tests[i].name) == 0) {
243 enabled_tests |= available_tests[i].flag;
244 break;
245 }
246 }
247 if(available_tests[i].name == NULL((void*)0))
248 usage(argv[0]);
249 }
250
251 break;
252 case 'v':
253 is_verbose = TRUE1;
254 break;
255 case 0:
256 break;
3
Execution continues on line 185
6
Execution continues on line 185
257 default:
258 usage(argv[0]);
259 break;
260 }
261 }
262
263 /* Print the version string. Bail out if --version was requested and
264 * continue otherwise.
265 */
266 puts(PACKAGE_STRING"rendercheck 1.4");
267 if (print_version)
268 return 0;
269
270 dpy = XOpenDisplay(display);
271 if (dpy == NULL((void*)0))
272 errx(1, "Couldn't open display.");
273 if (is_sync)
274 XSynchronize(dpy, 1);
275
276 if (!XRenderQueryExtension(dpy, &i, &i))
277 errx(1, "Render extension missing.");
278
279 XRenderQueryVersion(dpy, &maj, &min);
280 if (maj != 0 || min < 1)
281 errx(1, "Render extension version too low (%d.%d).", maj, min);
282
283 printf("Render extension version %d.%d\n", maj, min);
284
285 /* Conjoint/Disjoint were added in version 0.2, so disable those ops if
286 * the server doesn't support them.
287 */
288 if (min < 2) {
289 printf("Server doesn't support conjoint/disjoint ops, disabling.\n");
290 num_ops = PictOpSaturate13;
291 }
292
293 window.d = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy)((&((_XPrivDisplay)dpy)->screens[(((_XPrivDisplay)dpy)
->default_screen)])->root)
, 0, 0,
294 win_width, win_height, 0, 0, WhitePixel(dpy, 0)((&((_XPrivDisplay)dpy)->screens[0])->white_pixel));
295
296 as.override_redirect = True1;
297 XChangeWindowAttributes(dpy, window.d, CWOverrideRedirect(1L<<9), &as);
298
299 XGetWindowAttributes(dpy, window.d, &a);
300 window.format = XRenderFindVisualFormat(dpy, a.visual);
301 window.pict = XRenderCreatePicture(dpy, window.d,
302 window.format, 0, NULL((void*)0));
303 window.name = (char *)malloc(20);
304 if (window.name == NULL((void*)0))
305 errx(1, "malloc error");
306 describe_format(window.name, 20, window.format);
307 printf("Window format: %s\n", window.name);
308 strncat(window.name, " window", 20);
309 XSelectInput(dpy, window.d, ExposureMask(1L<<15));
310 XMapWindow(dpy, window.d);
311
312 /* We have to premultiply the alpha into the r, g, b values of the
313 * sample colors. Render colors are premultiplied with alpha, so r,g,b
314 * can never be greater than alpha.
315 */
316 for (i = 0; i < num_colors; i++) {
317 colors[i].r *= colors[i].a;
318 colors[i].g *= colors[i].a;
319 colors[i].b *= colors[i].a;
320 }
321
322 while (XNextEvent(dpy, &ev) == 0) {
323 if (ev.type == Expose12 && !ev.xexpose.count) {
324 if (do_tests(dpy, &window))
325 exit(0);
326 else
327 exit(1);
328 }
329 }
330
331 XCloseDisplay(dpy);
332 return 0;
333}