Bug Summary

File:render/animcur.c
Location:line 358, column 24
Description:Access to field 'foreRed' results in a dereference of a null pointer

Annotated Source Code

1/*
2 *
3 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Keith Packard makes no
12 * representations about the suitability of this software for any purpose. It
13 * is provided "as is" without express or implied warranty.
14 *
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24/*
25 * Animated cursors for X. Not specific to Render in any way, but
26 * stuck there because Render has the other cool cursor extension.
27 * Besides, everyone has Render.
28 *
29 * Implemented as a simple layer over the core cursor code; it
30 * creates composite cursors out of a set of static cursors and
31 * delta times between each image.
32 */
33
34#ifdef HAVE_DIX_CONFIG_H1
35#include <dix-config.h>
36#endif
37
38#include <X11/X.h>
39#include <X11/Xmd.h>
40#include "servermd.h"
41#include "scrnintstr.h"
42#include "dixstruct.h"
43#include "cursorstr.h"
44#include "dixfontstr.h"
45#include "opaque.h"
46#include "picturestr.h"
47#include "inputstr.h"
48#include "xace.h"
49
50typedef struct _AnimCurElt {
51 CursorPtr pCursor; /* cursor to show */
52 CARD32 delay; /* in ms */
53} AnimCurElt;
54
55typedef struct _AnimCur {
56 int nelt; /* number of elements in the elts array */
57 AnimCurElt *elts; /* actually allocated right after the structure */
58} AnimCurRec, *AnimCurPtr;
59
60typedef struct _AnimScrPriv {
61 CloseScreenProcPtr CloseScreen;
62
63 ScreenBlockHandlerProcPtr BlockHandler;
64
65 CursorLimitsProcPtr CursorLimits;
66 DisplayCursorProcPtr DisplayCursor;
67 SetCursorPositionProcPtr SetCursorPosition;
68 RealizeCursorProcPtr RealizeCursor;
69 UnrealizeCursorProcPtr UnrealizeCursor;
70 RecolorCursorProcPtr RecolorCursor;
71} AnimCurScreenRec, *AnimCurScreenPtr;
72
73static unsigned char empty[4];
74
75static CursorBits animCursorBits = {
76 empty, empty, 2, 1, 1, 0, 0, 1
77};
78
79static DevPrivateKeyRec AnimCurScreenPrivateKeyRec;
80
81#define AnimCurScreenPrivateKey(&AnimCurScreenPrivateKeyRec) (&AnimCurScreenPrivateKeyRec)
82
83#define IsAnimCur(c)((c) && ((c)->bits == &animCursorBits)) ((c) && ((c)->bits == &animCursorBits))
84#define GetAnimCur(c)((AnimCurPtr) ((((char *)(c) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR))))))
85#define GetAnimCurScreen(s)((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates,
(&AnimCurScreenPrivateKeyRec)))
((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey(&AnimCurScreenPrivateKeyRec)))
86#define SetAnimCurScreen(s,p)dixSetPrivate(&(s)->devPrivates, (&AnimCurScreenPrivateKeyRec
), p)
dixSetPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey(&AnimCurScreenPrivateKeyRec), p)
87
88#define Wrap(as,s,elt,func)(((as)->elt = (s)->elt), (s)->elt = func) (((as)->elt = (s)->elt), (s)->elt = func)
89#define Unwrap(as,s,elt)((s)->elt = (as)->elt) ((s)->elt = (as)->elt)
90
91static Bool
92AnimCurCloseScreen(ScreenPtr pScreen)
93{
94 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
95 Bool ret;
96
97 Unwrap(as, pScreen, CloseScreen)((pScreen)->CloseScreen = (as)->CloseScreen);
98
99 Unwrap(as, pScreen, CursorLimits)((pScreen)->CursorLimits = (as)->CursorLimits);
100 Unwrap(as, pScreen, DisplayCursor)((pScreen)->DisplayCursor = (as)->DisplayCursor);
101 Unwrap(as, pScreen, SetCursorPosition)((pScreen)->SetCursorPosition = (as)->SetCursorPosition
)
;
102 Unwrap(as, pScreen, RealizeCursor)((pScreen)->RealizeCursor = (as)->RealizeCursor);
103 Unwrap(as, pScreen, UnrealizeCursor)((pScreen)->UnrealizeCursor = (as)->UnrealizeCursor);
104 Unwrap(as, pScreen, RecolorCursor)((pScreen)->RecolorCursor = (as)->RecolorCursor);
105 SetAnimCurScreen(pScreen, 0)dixSetPrivate(&(pScreen)->devPrivates, (&AnimCurScreenPrivateKeyRec
), 0)
;
106 ret = (*pScreen->CloseScreen) (pScreen);
107 free(as);
108 return ret;
109}
110
111static void
112AnimCurCursorLimits(DeviceIntPtr pDev,
113 ScreenPtr pScreen,
114 CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox)
115{
116 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
117
118 Unwrap(as, pScreen, CursorLimits)((pScreen)->CursorLimits = (as)->CursorLimits);
119 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
120 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
121
122 (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor,
123 pHotBox, pTopLeftBox);
124 }
125 else {
126 (*pScreen->CursorLimits) (pDev, pScreen, pCursor, pHotBox, pTopLeftBox);
127 }
128 Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits)(((as)->CursorLimits = (pScreen)->CursorLimits), (pScreen
)->CursorLimits = AnimCurCursorLimits)
;
129}
130
131/*
132 * This has to be a screen block handler instead of a generic
133 * block handler so that it is well ordered with respect to the DRI
134 * block handler responsible for releasing the hardware to DRI clients
135 */
136
137static void
138AnimCurScreenBlockHandler(ScreenPtr pScreen,
139 void *pTimeout, void *pReadmask)
140{
141 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
142 DeviceIntPtr dev;
143 Bool activeDevice = FALSE0;
144 CARD32 now = 0, soonest = ~0; /* earliest time to wakeup again */
145
146 Unwrap(as, pScreen, BlockHandler)((pScreen)->BlockHandler = (as)->BlockHandler);
147
148 for (dev = inputInfo.devices; dev; dev = dev->next) {
149 if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
150 if (!activeDevice) {
151 now = GetTimeInMillis();
152 activeDevice = TRUE1;
153 }
154
155 if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
156 AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor)((AnimCurPtr) ((((char *)(dev->spriteInfo->anim.pCursor
) + (sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR))))))
;
157 int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
158 DisplayCursorProcPtr DisplayCursor;
159
160 /*
161 * Not a simple Unwrap/Wrap as this
162 * isn't called along the DisplayCursor
163 * wrapper chain.
164 */
165 DisplayCursor = pScreen->DisplayCursor;
166 pScreen->DisplayCursor = as->DisplayCursor;
167 (void) (*pScreen->DisplayCursor) (dev,
168 pScreen,
169 ac->elts[elt].pCursor);
170 as->DisplayCursor = pScreen->DisplayCursor;
171 pScreen->DisplayCursor = DisplayCursor;
172
173 dev->spriteInfo->anim.elt = elt;
174 dev->spriteInfo->anim.time = now + ac->elts[elt].delay;
175 }
176
177 if (soonest > dev->spriteInfo->anim.time)
178 soonest = dev->spriteInfo->anim.time;
179 }
180 }
181
182 if (activeDevice)
183 AdjustWaitForDelay(pTimeout, soonest - now);
184
185 (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
186 if (activeDevice)
187 Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler)(((as)->BlockHandler = (pScreen)->BlockHandler), (pScreen
)->BlockHandler = AnimCurScreenBlockHandler)
;
188 else
189 as->BlockHandler = NULL((void*)0);
190}
191
192static Bool
193AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
194{
195 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
196 Bool ret;
197
198 if (IsFloating(pDev))
199 return FALSE0;
200
201 Unwrap(as, pScreen, DisplayCursor)((pScreen)->DisplayCursor = (as)->DisplayCursor);
202 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
203 if (pCursor != pDev->spriteInfo->anim.pCursor) {
204 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
205
206 ret = (*pScreen->DisplayCursor)
207 (pDev, pScreen, ac->elts[0].pCursor);
208 if (ret) {
209 pDev->spriteInfo->anim.elt = 0;
210 pDev->spriteInfo->anim.time =
211 GetTimeInMillis() + ac->elts[0].delay;
212 pDev->spriteInfo->anim.pCursor = pCursor;
213 pDev->spriteInfo->anim.pScreen = pScreen;
214
215 if (!as->BlockHandler)
216 Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler)(((as)->BlockHandler = (pScreen)->BlockHandler), (pScreen
)->BlockHandler = AnimCurScreenBlockHandler)
;
217 }
218 }
219 else
220 ret = TRUE1;
221 }
222 else {
223 pDev->spriteInfo->anim.pCursor = 0;
224 pDev->spriteInfo->anim.pScreen = 0;
225 ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
226 }
227 Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor)(((as)->DisplayCursor = (pScreen)->DisplayCursor), (pScreen
)->DisplayCursor = AnimCurDisplayCursor)
;
228 return ret;
229}
230
231static Bool
232AnimCurSetCursorPosition(DeviceIntPtr pDev,
233 ScreenPtr pScreen, int x, int y, Bool generateEvent)
234{
235 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
236 Bool ret;
237
238 Unwrap(as, pScreen, SetCursorPosition)((pScreen)->SetCursorPosition = (as)->SetCursorPosition
)
;
239 if (pDev->spriteInfo->anim.pCursor) {
240 pDev->spriteInfo->anim.pScreen = pScreen;
241
242 if (!as->BlockHandler)
243 Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler)(((as)->BlockHandler = (pScreen)->BlockHandler), (pScreen
)->BlockHandler = AnimCurScreenBlockHandler)
;
244 }
245 ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
246 Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition)(((as)->SetCursorPosition = (pScreen)->SetCursorPosition
), (pScreen)->SetCursorPosition = AnimCurSetCursorPosition
)
;
247 return ret;
248}
249
250static Bool
251AnimCurRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
252{
253 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
254 Bool ret;
255
256 Unwrap(as, pScreen, RealizeCursor)((pScreen)->RealizeCursor = (as)->RealizeCursor);
257 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
)
258 ret = TRUE1;
259 else
260 ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor);
261 Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor)(((as)->RealizeCursor = (pScreen)->RealizeCursor), (pScreen
)->RealizeCursor = AnimCurRealizeCursor)
;
262 return ret;
263}
264
265static Bool
266AnimCurUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
267{
268 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
269 Bool ret;
270
271 Unwrap(as, pScreen, UnrealizeCursor)((pScreen)->UnrealizeCursor = (as)->UnrealizeCursor);
272 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
273 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
274 int i;
275
276 if (pScreen->myNum == 0)
277 for (i = 0; i < ac->nelt; i++)
278 FreeCursor(ac->elts[i].pCursor, 0);
279 ret = TRUE1;
280 }
281 else
282 ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
283 Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor)(((as)->UnrealizeCursor = (pScreen)->UnrealizeCursor), (
pScreen)->UnrealizeCursor = AnimCurUnrealizeCursor)
;
284 return ret;
285}
286
287static void
288AnimCurRecolorCursor(DeviceIntPtr pDev,
289 ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
290{
291 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
292
293 Unwrap(as, pScreen, RecolorCursor)((pScreen)->RecolorCursor = (as)->RecolorCursor);
294 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
295 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
296 int i;
297
298 for (i = 0; i < ac->nelt; i++)
299 (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor,
300 displayed &&
301 pDev->spriteInfo->anim.elt == i);
302 }
303 else
304 (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed);
305 Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor)(((as)->RecolorCursor = (pScreen)->RecolorCursor), (pScreen
)->RecolorCursor = AnimCurRecolorCursor)
;
306}
307
308Bool
309AnimCurInit(ScreenPtr pScreen)
310{
311 AnimCurScreenPtr as;
312
313 if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
314 return FALSE0;
315
316 as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec));
317 if (!as)
318 return FALSE0;
319 Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen)(((as)->CloseScreen = (pScreen)->CloseScreen), (pScreen
)->CloseScreen = AnimCurCloseScreen)
;
320
321 as->BlockHandler = NULL((void*)0);
322
323 Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits)(((as)->CursorLimits = (pScreen)->CursorLimits), (pScreen
)->CursorLimits = AnimCurCursorLimits)
;
324 Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor)(((as)->DisplayCursor = (pScreen)->DisplayCursor), (pScreen
)->DisplayCursor = AnimCurDisplayCursor)
;
325 Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition)(((as)->SetCursorPosition = (pScreen)->SetCursorPosition
), (pScreen)->SetCursorPosition = AnimCurSetCursorPosition
)
;
326 Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor)(((as)->RealizeCursor = (pScreen)->RealizeCursor), (pScreen
)->RealizeCursor = AnimCurRealizeCursor)
;
327 Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor)(((as)->UnrealizeCursor = (pScreen)->UnrealizeCursor), (
pScreen)->UnrealizeCursor = AnimCurUnrealizeCursor)
;
328 Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor)(((as)->RecolorCursor = (pScreen)->RecolorCursor), (pScreen
)->RecolorCursor = AnimCurRecolorCursor)
;
329 SetAnimCurScreen(pScreen, as)dixSetPrivate(&(pScreen)->devPrivates, (&AnimCurScreenPrivateKeyRec
), as)
;
330 return TRUE1;
331}
332
333int
334AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
335 CursorPtr *ppCursor, ClientPtr client, XID cid)
336{
337 CursorPtr pCursor;
338 int rc, i;
339 AnimCurPtr ac;
340
341 for (i = 0; i < screenInfo.numScreens; i++)
1
Loop condition is false. Execution continues on line 345
342 if (!GetAnimCurScreen(screenInfo.screens[i])((AnimCurScreenPtr)dixLookupPrivate(&(screenInfo.screens[
i])->devPrivates, (&AnimCurScreenPrivateKeyRec)))
)
343 return BadImplementation17;
344
345 for (i = 0; i < ncursor; i++)
2
Assuming 'i' is < 'ncursor'
3
Loop condition is true. Entering loop body
5
Assuming 'i' is >= 'ncursor'
6
Loop condition is false. Execution continues on line 349
346 if (IsAnimCur(cursors[i])((cursors[i]) && ((cursors[i])->bits == &animCursorBits
))
)
4
Within the expansion of the macro 'IsAnimCur':
a
Assuming pointer value is null
347 return BadMatch8;
348
349 pCursor = (CursorPtr) calloc(CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR)) +
350 sizeof(AnimCurRec) +
351 ncursor * sizeof(AnimCurElt), 1);
352 if (!pCursor)
7
Assuming 'pCursor' is non-null
8
Taking false branch
353 return BadAlloc11;
354 dixInitPrivates(pCursor, pCursor + 1, PRIVATE_CURSOR)_dixInitPrivates(&(pCursor)->devPrivates, (pCursor + 1
), PRIVATE_CURSOR);
;
355 pCursor->bits = &animCursorBits;
356 pCursor->refcnt = 1;
357
358 pCursor->foreRed = cursors[0]->foreRed;
9
Access to field 'foreRed' results in a dereference of a null pointer
359 pCursor->foreGreen = cursors[0]->foreGreen;
360 pCursor->foreBlue = cursors[0]->foreBlue;
361
362 pCursor->backRed = cursors[0]->backRed;
363 pCursor->backGreen = cursors[0]->backGreen;
364 pCursor->backBlue = cursors[0]->backBlue;
365
366 pCursor->id = cid;
367
368 /* security creation/labeling check */
369 rc = XaceHook(XACE_RESOURCE_ACCESS2, client, cid, RT_CURSOR((RESTYPE)5), pCursor,
370 RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3));
371 if (rc != Success0) {
372 dixFiniPrivates(pCursor, PRIVATE_CURSOR)_dixFiniPrivates((pCursor)->devPrivates,PRIVATE_CURSOR);
373 free(pCursor);
374 return rc;
375 }
376
377 /*
378 * Fill in the AnimCurRec
379 */
380 animCursorBits.refcnt++;
381 ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
382 ac->nelt = ncursor;
383 ac->elts = (AnimCurElt *) (ac + 1);
384
385 for (i = 0; i < ncursor; i++) {
386 ac->elts[i].pCursor = RefCursor(cursors[i]);
387 ac->elts[i].delay = deltas[i];
388 }
389
390 *ppCursor = pCursor;
391 return Success0;
392}