Bug Summary

File:xlibclient.c
Location:line 182, column 16
Description:Potential leak of memory pointed to by 'pPriv'

Annotated Source Code

1/*
2 * Permission is hereby granted, free of charge, to any person obtaining a
3 * copy of this software and associated documentation files (the "Software"),
4 * to deal in the Software without restriction, including without limitation
5 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
6 * and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice (including the next
10 * paragraph) shall be included in all copies or substantial portions of the
11 * Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19 * DEALINGS IN THE SOFTWARE.
20 *
21 * Authors:
22 *
23 * Paulo Zanoni <pzanoni@mandriva.com>
24 * Tuan Bui <tuanbui918@gmail.com>
25 * Colin Cornaby <colin.cornaby@mac.com>
26 * Timothy Fleck <tim.cs.pdx@gmail.com>
27 * Colin Hill <colin.james.hill@gmail.com>
28 * Weseung Hwang <weseung@gmail.com>
29 * Nathaniel Way <nathanielcw@hotmail.com>
30 */
31
32#include <stdlib.h>
33
34#include <sys/ipc.h>
35#include <sys/shm.h>
36
37#include <X11/Xlib.h>
38#include <X11/Xutil.h>
39#include <X11/XKBlib.h>
40#include <X11/extensions/XShm.h>
41
42#include <xorg-server.h>
43#include <xf86.h>
44
45#ifdef HAVE_CONFIG_H1
46#include "config.h"
47#endif
48
49#include "client.h"
50
51#include "nested_input.h"
52
53struct NestedClientPrivate {
54 Display *display;
55 int screenNumber;
56 Screen *screen;
57 Window rootWindow;
58 Window window;
59 XImage *img;
60 GC gc;
61 Boolint usingShm;
62 XShmSegmentInfo shminfo;
63 int scrnIndex; /* stored only for xf86DrvMsg usage */
64 Cursor mycursor; /* Test cursor */
65 Pixmap bitmapNoData;
66 XColor color1;
67 DeviceIntPtr dev; // The pointer to the input device. Passed back to the
68 // input driver when posting input events.
69
70 struct {
71 int op;
72 int event;
73 int error;
74 int major;
75 int minor;
76 } xkb;
77};
78
79/* Checks if a display is open */
80Boolint
81NestedClientCheckDisplay(char *displayName) {
82 Display *d;
83
84 d = XOpenDisplay(displayName);
85 if (!d) {
86 return FALSE0;
87 } else {
88 XCloseDisplay(d);
89 return TRUE1;
90 }
91}
92
93Boolint
94NestedClientValidDepth(int depth) {
95 /* XXX: implement! */
96 return TRUE1;
97}
98
99static Boolint
100NestedClientTryXShm(NestedClientPrivatePtr pPriv, int scrnIndex, int width, int height, int depth) {
101 int shmMajor, shmMinor;
102 Boolint hasSharedPixmaps;
103
104 if (!XShmQueryExtension(pPriv->display)) {
105 xf86DrvMsg(scrnIndex, X_INFO, "XShmQueryExtension failed. Dropping XShm support.\n");
106
107 return FALSE0;
108 }
109
110 if (XShmQueryVersion(pPriv->display, &shmMajor, &shmMinor,
111 &hasSharedPixmaps)) {
112 xf86DrvMsg(scrnIndex, X_INFO,
113 "XShm extension version %d.%d %s shared pixmaps\n",
114 shmMajor, shmMinor, (hasSharedPixmaps) ? "with" : "without");
115 }
116
117 pPriv->img = XShmCreateImage(pPriv->display,
118 DefaultVisualOfScreen(pPriv->screen)((pPriv->screen)->root_visual),
119 depth,
120 ZPixmap2,
121 NULL((void*)0), /* data */
122 &pPriv->shminfo,
123 width,
124 height);
125
126 if (!pPriv->img) {
127 xf86DrvMsg(scrnIndex, X_ERROR, "XShmCreateImage failed. Dropping XShm support.\n");
128 return FALSE0;
129 }
130
131 /* XXX: change the 0777 mask? */
132 pPriv->shminfo.shmid = shmget(IPC_PRIVATE((key_t)0),
133 pPriv->img->bytes_per_line *
134 pPriv->img->height,
135 IPC_CREAT001000 | 0777);
136
137 if (pPriv->shminfo.shmid == -1) {
138 xf86DrvMsg(scrnIndex, X_ERROR, "shmget failed. Dropping XShm support.\n");
139 XDestroyImage(pPriv->img)((*((pPriv->img)->f.destroy_image))((pPriv->img)));
140 return FALSE0;
141 }
142
143 pPriv->shminfo.shmaddr = (char *)shmat(pPriv->shminfo.shmid, NULL((void*)0), 0);
144
145 if (pPriv->shminfo.shmaddr == (char *) -1) {
146 xf86DrvMsg(scrnIndex, X_ERROR, "shmaddr failed. Dropping XShm support.\n");
147 XDestroyImage(pPriv->img)((*((pPriv->img)->f.destroy_image))((pPriv->img)));
148 return FALSE0;
149 }
150
151 pPriv->img->data = pPriv->shminfo.shmaddr;
152 pPriv->shminfo.readOnly = FALSE0;
153 XShmAttach(pPriv->display, &pPriv->shminfo);
154 pPriv->usingShm = TRUE1;
155
156 return TRUE1;
157}
158
159
160NestedClientPrivatePtr
161NestedClientCreateScreen(int scrnIndex,
162 char *displayName,
163 int width,
164 int height,
165 int originX,
166 int originY,
167 int depth,
168 int bitsPerPixel,
169 Pixel *retRedMask,
170 Pixel *retGreenMask,
171 Pixel *retBlueMask) {
172 NestedClientPrivatePtr pPriv;
173 XSizeHints sizeHints;
174 Boolint supported;
175 char windowTitle[32];
176
177 pPriv = malloc(sizeof(struct NestedClientPrivate));
1
Memory is allocated
178 pPriv->scrnIndex = scrnIndex;
179
180 pPriv->display = XOpenDisplay(displayName);
181 if (!pPriv->display)
2
Taking true branch
182 return NULL((void*)0);
3
Within the expansion of the macro 'NULL':
a
Potential leak of memory pointed to by 'pPriv'
183
184 supported = XkbQueryExtension(pPriv->display, &pPriv->xkb.op, &pPriv->xkb.event,
185 &pPriv->xkb.error, &pPriv->xkb.major, &pPriv->xkb.minor);
186 if (!supported) {
187 xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "The remote server does not support the XKEYBOARD extension.\n");
188 XCloseDisplay(pPriv->display);
189 return NULL((void*)0);
190 }
191
192 pPriv->screenNumber = DefaultScreen(pPriv->display)(((_XPrivDisplay)(pPriv->display))->default_screen);
193 pPriv->screen = ScreenOfDisplay(pPriv->display, pPriv->screenNumber)(&((_XPrivDisplay)(pPriv->display))->screens[pPriv->
screenNumber])
;
194 pPriv->rootWindow = RootWindow(pPriv->display, pPriv->screenNumber)((&((_XPrivDisplay)(pPriv->display))->screens[pPriv
->screenNumber])->root)
;
195 pPriv->gc = DefaultGC(pPriv->display, pPriv->screenNumber)((&((_XPrivDisplay)(pPriv->display))->screens[pPriv
->screenNumber])->default_gc)
;
196
197 pPriv->window = XCreateSimpleWindow(pPriv->display, pPriv->rootWindow,
198 originX, originY, width, height, 0, 0, 0);
199
200 sizeHints.flags = PPosition(1L << 2) | PSize(1L << 3) | PMinSize(1L << 4) | PMaxSize(1L << 5);
201 sizeHints.min_width = width;
202 sizeHints.max_width = width;
203 sizeHints.min_height = height;
204 sizeHints.max_height = height;
205 XSetWMNormalHints(pPriv->display, pPriv->window, &sizeHints);
206
207 snprintf(windowTitle, sizeof(windowTitle), "Screen %d", scrnIndex)__builtin___snprintf_chk (windowTitle, sizeof(windowTitle), 0
, __builtin_object_size (windowTitle, 2 > 1 ? 1 : 0), "Screen %d"
, scrnIndex)
;
208
209 XStoreName(pPriv->display, pPriv->window, windowTitle);
210
211 XMapWindow(pPriv->display, pPriv->window);
212
213 XSelectInput(pPriv->display, pPriv->window, ExposureMask(1L<<15) |
214 PointerMotionMask(1L<<6) | EnterWindowMask(1L<<4) | LeaveWindowMask(1L<<5) |
215 ButtonPressMask(1L<<2) | ButtonReleaseMask(1L<<3) | KeyPressMask(1L<<0) |
216 KeyReleaseMask(1L<<1));
217
218 if (!NestedClientTryXShm(pPriv, scrnIndex, width, height, depth)) {
219 pPriv->img = XCreateImage(pPriv->display,
220 DefaultVisualOfScreen(pPriv->screen)((pPriv->screen)->root_visual),
221 depth,
222 ZPixmap2,
223 0, /* offset */
224 NULL((void*)0), /* data */
225 width,
226 height,
227 32, /* XXX: bitmap_pad */
228 0 /* XXX: bytes_per_line */);
229
230 if (!pPriv->img)
231 return NULL((void*)0);
232
233 pPriv->img->data = malloc(pPriv->img->bytes_per_line * pPriv->img->height);
234 pPriv->usingShm = FALSE0;
235 }
236
237 if (!pPriv->img->data)
238 return NULL((void*)0);
239
240 NestedClientHideCursor(pPriv); /* Hide cursor */
241
242#if 0
243xf86DrvMsg(scrnIndex, X_INFO, "width: %d\n", pPriv->img->width);
244xf86DrvMsg(scrnIndex, X_INFO, "height: %d\n", pPriv->img->height);
245xf86DrvMsg(scrnIndex, X_INFO, "xoffset: %d\n", pPriv->img->xoffset);
246xf86DrvMsg(scrnIndex, X_INFO, "depth: %d\n", pPriv->img->depth);
247xf86DrvMsg(scrnIndex, X_INFO, "bpp: %d\n", pPriv->img->bits_per_pixel);
248xf86DrvMsg(scrnIndex, X_INFO, "red_mask: 0x%lx\n", pPriv->img->red_mask);
249xf86DrvMsg(scrnIndex, X_INFO, "gre_mask: 0x%lx\n", pPriv->img->green_mask);
250xf86DrvMsg(scrnIndex, X_INFO, "blu_mask: 0x%lx\n", pPriv->img->blue_mask);
251#endif
252
253 *retRedMask = pPriv->img->red_mask;
254 *retGreenMask = pPriv->img->green_mask;
255 *retBlueMask = pPriv->img->blue_mask;
256
257 XEvent ev;
258 while (1) {
259 XNextEvent(pPriv->display, &ev);
260 if (ev.type == Expose12) {
261 break;
262 }
263 }
264
265 pPriv->dev = (DeviceIntPtr)NULL((void*)0);
266
267 return pPriv;
268}
269
270void NestedClientHideCursor(NestedClientPrivatePtr pPriv) {
271 char noData[]= {0,0,0,0,0,0,0,0};
272 pPriv->color1.red = pPriv->color1.green = pPriv->color1.blue = 0;
273
274 pPriv->bitmapNoData = XCreateBitmapFromData(pPriv->display,
275 pPriv->window, noData, 7, 7);
276
277 pPriv->mycursor = XCreatePixmapCursor(pPriv->display,
278 pPriv->bitmapNoData, pPriv->bitmapNoData,
279 &pPriv->color1, &pPriv->color1, 0, 0);
280
281 XDefineCursor(pPriv->display, pPriv->window, pPriv->mycursor);
282 XFreeCursor(pPriv->display, pPriv->mycursor);
283}
284
285char *
286NestedClientGetFrameBuffer(NestedClientPrivatePtr pPriv) {
287 return pPriv->img->data;
288}
289
290void
291NestedClientUpdateScreen(NestedClientPrivatePtr pPriv, int16_t x1,
292 int16_t y1, int16_t x2, int16_t y2) {
293 if (pPriv->usingShm) {
294 XShmPutImage(pPriv->display, pPriv->window, pPriv->gc, pPriv->img,
295 x1, y1, x1, y1, x2 - x1, y2 - y1, FALSE0);
296 /* Without this sync we get some freezes, probably due to some lock
297 * in the shm usage */
298 XSync(pPriv->display, FALSE0);
299 } else {
300 XPutImage(pPriv->display, pPriv->window, pPriv->gc, pPriv->img,
301 x1, y1, x1, y1, x2 - x1, y2 - y1);
302 }
303}
304
305void
306NestedClientCheckEvents(NestedClientPrivatePtr pPriv) {
307 XEvent ev;
308
309 while(XCheckMaskEvent(pPriv->display, ~0, &ev)) {
310 switch (ev.type) {
311 case Expose12:
312 NestedClientUpdateScreen(pPriv,
313 ((XExposeEvent*)&ev)->x,
314 ((XExposeEvent*)&ev)->y,
315 ((XExposeEvent*)&ev)->x +
316 ((XExposeEvent*)&ev)->width,
317 ((XExposeEvent*)&ev)->y +
318 ((XExposeEvent*)&ev)->height);
319 break;
320
321 case MotionNotify6:
322 if (!pPriv->dev) {
323 xf86DrvMsg(pPriv->scrnIndex, X_INFO, "Input device is not yet initialized, ignoring input.\n");
324 break;
325 }
326
327 NestedInputPostMouseMotionEvent(pPriv->dev,
328 ((XMotionEvent*)&ev)->x,
329 ((XMotionEvent*)&ev)->y);
330 break;
331
332 case ButtonPress4:
333 case ButtonRelease5:
334 if (!pPriv->dev) {
335 xf86DrvMsg(pPriv->scrnIndex, X_INFO, "Input device is not yet initialized, ignoring input.\n");
336 break;
337 }
338
339 NestedInputPostButtonEvent(pPriv->dev, ev.xbutton.button, ev.type == ButtonPress4);
340 break;
341
342 case KeyPress2:
343 case KeyRelease3:
344 if (!pPriv->dev) {
345 xf86DrvMsg(pPriv->scrnIndex, X_INFO, "Input device is not yet initialized, ignoring input.\n");
346 break;
347 }
348
349 NestedInputPostKeyboardEvent(pPriv->dev, ev.xkey.keycode, ev.type == KeyPress2);
350 break;
351 }
352 }
353}
354
355void
356NestedClientCloseScreen(NestedClientPrivatePtr pPriv) {
357 if (pPriv->usingShm) {
358 XShmDetach(pPriv->display, &pPriv->shminfo);
359 shmdt(pPriv->shminfo.shmaddr);
360 }
361
362 XDestroyImage(pPriv->img)((*((pPriv->img)->f.destroy_image))((pPriv->img)));
363 XCloseDisplay(pPriv->display);
364}
365
366void
367NestedClientSetDevicePtr(NestedClientPrivatePtr pPriv, DeviceIntPtr dev) {
368 pPriv->dev = dev;
369}
370
371int
372NestedClientGetFileDescriptor(NestedClientPrivatePtr pPriv) {
373 return ConnectionNumber(pPriv->display)(((_XPrivDisplay)(pPriv->display))->fd);
374}
375
376Boolint NestedClientGetKeyboardMappings(NestedClientPrivatePtr pPriv, KeySymsPtr keySyms, CARD8 *modmap, XkbControlsPtr ctrls) {
377 XModifierKeymap *modifier_keymap;
378 KeySym *keymap;
379 int mapWidth;
380 int min_keycode, max_keycode;
381 int i, j;
382 XkbDescPtr xkb;
383
384 XDisplayKeycodes(pPriv->display, &min_keycode, &max_keycode);
385 keymap = XGetKeyboardMapping(pPriv->display,
386 min_keycode,
387 max_keycode - min_keycode + 1,
388 &mapWidth);
389
390 memset(modmap, 0, sizeof(CARD8) * MAP_LENGTH)__builtin___memset_chk (modmap, 0, sizeof(CARD8) * 256, __builtin_object_size
(modmap, 0))
;
391 modifier_keymap = XGetModifierMapping(pPriv->display);
392 for (j = 0; j < 8; j++)
393 for(i = 0; i < modifier_keymap->max_keypermod; i++) {
394 CARD8 keycode;
395 if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
396 modmap[keycode] |= 1<<j;
397 }
398 XFreeModifiermap(modifier_keymap);
399
400 keySyms->minKeyCode = min_keycode;
401 keySyms->maxKeyCode = max_keycode;
402 keySyms->mapWidth = mapWidth;
403 keySyms->map = keymap;
404
405 xkb = XkbGetKeyboard(pPriv->display, XkbGBN_AllComponentsMask(0xff), XkbUseCoreKbd0x0100);
406 if (xkb == NULL((void*)0) || xkb->geom == NULL((void*)0)) {
407 xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "Couldn't get XKB keyboard.\n");
408 free(keymap);
409 return FALSE0;
410 }
411
412 if(XkbGetControls(pPriv->display, XkbAllControlsMask(0xF8001FFF), xkb) != Success0) {
413 xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "Couldn't get XKB keyboard controls.\n");
414 free(keymap);
415 return FALSE0;
416 }
417
418 memcpy(ctrls, xkb->ctrls, sizeof(XkbControlsRec))__builtin___memcpy_chk (ctrls, xkb->ctrls, sizeof(XkbControlsRec
), __builtin_object_size (ctrls, 0))
;
419 XkbFreeKeyboard(xkb, 0, False0);
420 return TRUE1;
421}