Bug Summary

File:render/animcur.c
Location:line 361, 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 CursorLimitsProcPtr CursorLimits;
63 DisplayCursorProcPtr DisplayCursor;
64 SetCursorPositionProcPtr SetCursorPosition;
65 RealizeCursorProcPtr RealizeCursor;
66 UnrealizeCursorProcPtr UnrealizeCursor;
67 RecolorCursorProcPtr RecolorCursor;
68 OsTimerPtr timer;
69 Bool timer_set;
70} AnimCurScreenRec, *AnimCurScreenPtr;
71
72static unsigned char empty[4];
73
74static CursorBits animCursorBits = {
75 empty, empty, 2, 1, 1, 0, 0, 1
76};
77
78static DevPrivateKeyRec AnimCurScreenPrivateKeyRec;
79
80#define AnimCurScreenPrivateKey(&AnimCurScreenPrivateKeyRec) (&AnimCurScreenPrivateKeyRec)
81
82#define IsAnimCur(c)((c) && ((c)->bits == &animCursorBits)) ((c) && ((c)->bits == &animCursorBits))
83#define GetAnimCur(c)((AnimCurPtr) ((((char *)(c) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR))))))
84#define GetAnimCurScreen(s)((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates,
(&AnimCurScreenPrivateKeyRec)))
((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey(&AnimCurScreenPrivateKeyRec)))
85#define SetAnimCurScreen(s,p)dixSetPrivate(&(s)->devPrivates, (&AnimCurScreenPrivateKeyRec
), p)
dixSetPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey(&AnimCurScreenPrivateKeyRec), p)
86
87#define Wrap(as,s,elt,func)(((as)->elt = (s)->elt), (s)->elt = func) (((as)->elt = (s)->elt), (s)->elt = func)
88#define Unwrap(as,s,elt)((s)->elt = (as)->elt) ((s)->elt = (as)->elt)
89
90static Bool
91AnimCurCloseScreen(ScreenPtr pScreen)
92{
93 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
94 Bool ret;
95
96 Unwrap(as, pScreen, CloseScreen)((pScreen)->CloseScreen = (as)->CloseScreen);
97
98 Unwrap(as, pScreen, CursorLimits)((pScreen)->CursorLimits = (as)->CursorLimits);
99 Unwrap(as, pScreen, DisplayCursor)((pScreen)->DisplayCursor = (as)->DisplayCursor);
100 Unwrap(as, pScreen, SetCursorPosition)((pScreen)->SetCursorPosition = (as)->SetCursorPosition
)
;
101 Unwrap(as, pScreen, RealizeCursor)((pScreen)->RealizeCursor = (as)->RealizeCursor);
102 Unwrap(as, pScreen, UnrealizeCursor)((pScreen)->UnrealizeCursor = (as)->UnrealizeCursor);
103 Unwrap(as, pScreen, RecolorCursor)((pScreen)->RecolorCursor = (as)->RecolorCursor);
104 SetAnimCurScreen(pScreen, 0)dixSetPrivate(&(pScreen)->devPrivates, (&AnimCurScreenPrivateKeyRec
), 0)
;
105 ret = (*pScreen->CloseScreen) (pScreen);
106 free(as);
107 return ret;
108}
109
110static void
111AnimCurCursorLimits(DeviceIntPtr pDev,
112 ScreenPtr pScreen,
113 CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox)
114{
115 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
116
117 Unwrap(as, pScreen, CursorLimits)((pScreen)->CursorLimits = (as)->CursorLimits);
118 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
119 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
120
121 (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor,
122 pHotBox, pTopLeftBox);
123 }
124 else {
125 (*pScreen->CursorLimits) (pDev, pScreen, pCursor, pHotBox, pTopLeftBox);
126 }
127 Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits)(((as)->CursorLimits = (pScreen)->CursorLimits), (pScreen
)->CursorLimits = AnimCurCursorLimits)
;
128}
129
130/*
131 * The cursor animation timer has expired, go display any relevant cursor changes
132 * and compute a new timeout value
133 */
134
135static CARD32
136AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
137{
138 ScreenPtr pScreen = arg;
139 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
140 DeviceIntPtr dev;
141 Bool activeDevice = FALSE0;
142 CARD32 soonest = ~0; /* earliest time to wakeup again */
143
144 for (dev = inputInfo.devices; dev; dev = dev->next) {
145 if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
146 if (!activeDevice)
147 activeDevice = TRUE1;
148
149 if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
150 AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor)((AnimCurPtr) ((((char *)(dev->spriteInfo->anim.pCursor
) + (sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR))))))
;
151 int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
152 DisplayCursorProcPtr DisplayCursor;
153
154 /*
155 * Not a simple Unwrap/Wrap as this
156 * isn't called along the DisplayCursor
157 * wrapper chain.
158 */
159 DisplayCursor = pScreen->DisplayCursor;
160 pScreen->DisplayCursor = as->DisplayCursor;
161 (void) (*pScreen->DisplayCursor) (dev,
162 pScreen,
163 ac->elts[elt].pCursor);
164 as->DisplayCursor = pScreen->DisplayCursor;
165 pScreen->DisplayCursor = DisplayCursor;
166
167 dev->spriteInfo->anim.elt = elt;
168 dev->spriteInfo->anim.time = now + ac->elts[elt].delay;
169 }
170
171 if (soonest > dev->spriteInfo->anim.time)
172 soonest = dev->spriteInfo->anim.time;
173 }
174 }
175
176 if (activeDevice)
177 TimerSet(as->timer, TimerAbsolute(1<<0), soonest, AnimCurTimerNotify, pScreen);
178 else
179 as->timer_set = FALSE0;
180
181 return 0;
182}
183
184static Bool
185AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
186{
187 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
188 Bool ret;
189
190 if (IsFloating(pDev))
191 return FALSE0;
192
193 Unwrap(as, pScreen, DisplayCursor)((pScreen)->DisplayCursor = (as)->DisplayCursor);
194 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
195 if (pCursor != pDev->spriteInfo->anim.pCursor) {
196 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
197
198 ret = (*pScreen->DisplayCursor)
199 (pDev, pScreen, ac->elts[0].pCursor);
200 if (ret) {
201 pDev->spriteInfo->anim.elt = 0;
202 pDev->spriteInfo->anim.time =
203 GetTimeInMillis() + ac->elts[0].delay;
204 pDev->spriteInfo->anim.pCursor = pCursor;
205 pDev->spriteInfo->anim.pScreen = pScreen;
206
207 if (!as->timer_set) {
208 TimerSet(as->timer, TimerAbsolute(1<<0), pDev->spriteInfo->anim.time,
209 AnimCurTimerNotify, pScreen);
210 as->timer_set = TRUE1;
211 }
212 }
213 }
214 else
215 ret = TRUE1;
216 }
217 else {
218 pDev->spriteInfo->anim.pCursor = 0;
219 pDev->spriteInfo->anim.pScreen = 0;
220 ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
221 }
222 Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor)(((as)->DisplayCursor = (pScreen)->DisplayCursor), (pScreen
)->DisplayCursor = AnimCurDisplayCursor)
;
223 return ret;
224}
225
226static Bool
227AnimCurSetCursorPosition(DeviceIntPtr pDev,
228 ScreenPtr pScreen, int x, int y, Bool generateEvent)
229{
230 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
231 Bool ret;
232
233 Unwrap(as, pScreen, SetCursorPosition)((pScreen)->SetCursorPosition = (as)->SetCursorPosition
)
;
234 if (pDev->spriteInfo->anim.pCursor) {
235 pDev->spriteInfo->anim.pScreen = pScreen;
236
237 if (!as->timer_set) {
238 TimerSet(as->timer, TimerAbsolute(1<<0), pDev->spriteInfo->anim.time,
239 AnimCurTimerNotify, pScreen);
240 as->timer_set = TRUE1;
241 }
242 }
243 ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
244 Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition)(((as)->SetCursorPosition = (pScreen)->SetCursorPosition
), (pScreen)->SetCursorPosition = AnimCurSetCursorPosition
)
;
245 return ret;
246}
247
248static Bool
249AnimCurRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
250{
251 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
252 Bool ret;
253
254 Unwrap(as, pScreen, RealizeCursor)((pScreen)->RealizeCursor = (as)->RealizeCursor);
255 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
)
256 ret = TRUE1;
257 else
258 ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor);
259 Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor)(((as)->RealizeCursor = (pScreen)->RealizeCursor), (pScreen
)->RealizeCursor = AnimCurRealizeCursor)
;
260 return ret;
261}
262
263static Bool
264AnimCurUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
265{
266 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
267 Bool ret;
268
269 Unwrap(as, pScreen, UnrealizeCursor)((pScreen)->UnrealizeCursor = (as)->UnrealizeCursor);
270 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
271 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
272 int i;
273
274 if (pScreen->myNum == 0)
275 for (i = 0; i < ac->nelt; i++)
276 FreeCursor(ac->elts[i].pCursor, 0);
277 ret = TRUE1;
278 }
279 else
280 ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
281 Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor)(((as)->UnrealizeCursor = (pScreen)->UnrealizeCursor), (
pScreen)->UnrealizeCursor = AnimCurUnrealizeCursor)
;
282 return ret;
283}
284
285static void
286AnimCurRecolorCursor(DeviceIntPtr pDev,
287 ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
288{
289 AnimCurScreenPtr as = GetAnimCurScreen(pScreen)((AnimCurScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&AnimCurScreenPrivateKeyRec)))
;
290
291 Unwrap(as, pScreen, RecolorCursor)((pScreen)->RecolorCursor = (as)->RecolorCursor);
292 if (IsAnimCur(pCursor)((pCursor) && ((pCursor)->bits == &animCursorBits
))
) {
293 AnimCurPtr ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
294 int i;
295
296 for (i = 0; i < ac->nelt; i++)
297 (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor,
298 displayed &&
299 pDev->spriteInfo->anim.elt == i);
300 }
301 else
302 (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed);
303 Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor)(((as)->RecolorCursor = (pScreen)->RecolorCursor), (pScreen
)->RecolorCursor = AnimCurRecolorCursor)
;
304}
305
306Bool
307AnimCurInit(ScreenPtr pScreen)
308{
309 AnimCurScreenPtr as;
310
311 if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
312 return FALSE0;
313
314 as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec));
315 if (!as)
316 return FALSE0;
317 as->timer = TimerSet(NULL((void*)0), TimerAbsolute(1<<0), 0, AnimCurTimerNotify, pScreen);
318 if (!as->timer) {
319 free(as);
320 return FALSE0;
321 }
322 as->timer_set = FALSE0;
323
324 Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen)(((as)->CloseScreen = (pScreen)->CloseScreen), (pScreen
)->CloseScreen = AnimCurCloseScreen)
;
325
326 Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits)(((as)->CursorLimits = (pScreen)->CursorLimits), (pScreen
)->CursorLimits = AnimCurCursorLimits)
;
327 Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor)(((as)->DisplayCursor = (pScreen)->DisplayCursor), (pScreen
)->DisplayCursor = AnimCurDisplayCursor)
;
328 Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition)(((as)->SetCursorPosition = (pScreen)->SetCursorPosition
), (pScreen)->SetCursorPosition = AnimCurSetCursorPosition
)
;
329 Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor)(((as)->RealizeCursor = (pScreen)->RealizeCursor), (pScreen
)->RealizeCursor = AnimCurRealizeCursor)
;
330 Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor)(((as)->UnrealizeCursor = (pScreen)->UnrealizeCursor), (
pScreen)->UnrealizeCursor = AnimCurUnrealizeCursor)
;
331 Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor)(((as)->RecolorCursor = (pScreen)->RecolorCursor), (pScreen
)->RecolorCursor = AnimCurRecolorCursor)
;
332 SetAnimCurScreen(pScreen, as)dixSetPrivate(&(pScreen)->devPrivates, (&AnimCurScreenPrivateKeyRec
), as)
;
333 return TRUE1;
334}
335
336int
337AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
338 CursorPtr *ppCursor, ClientPtr client, XID cid)
339{
340 CursorPtr pCursor;
341 int rc, i;
342 AnimCurPtr ac;
343
344 for (i = 0; i < screenInfo.numScreens; i++)
1
Loop condition is false. Execution continues on line 348
345 if (!GetAnimCurScreen(screenInfo.screens[i])((AnimCurScreenPtr)dixLookupPrivate(&(screenInfo.screens[
i])->devPrivates, (&AnimCurScreenPrivateKeyRec)))
)
346 return BadImplementation17;
347
348 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 352
349 if (IsAnimCur(cursors[i])((cursors[i]) && ((cursors[i])->bits == &animCursorBits
))
)
4
Within the expansion of the macro 'IsAnimCur':
a
Assuming pointer value is null
350 return BadMatch8;
351
352 pCursor = (CursorPtr) calloc(CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR)) +
353 sizeof(AnimCurRec) +
354 ncursor * sizeof(AnimCurElt), 1);
355 if (!pCursor)
7
Assuming 'pCursor' is non-null
8
Taking false branch
356 return BadAlloc11;
357 dixInitPrivates(pCursor, pCursor + 1, PRIVATE_CURSOR)_dixInitPrivates(&(pCursor)->devPrivates, (pCursor + 1
), PRIVATE_CURSOR);
;
358 pCursor->bits = &animCursorBits;
359 pCursor->refcnt = 1;
360
361 pCursor->foreRed = cursors[0]->foreRed;
9
Access to field 'foreRed' results in a dereference of a null pointer
362 pCursor->foreGreen = cursors[0]->foreGreen;
363 pCursor->foreBlue = cursors[0]->foreBlue;
364
365 pCursor->backRed = cursors[0]->backRed;
366 pCursor->backGreen = cursors[0]->backGreen;
367 pCursor->backBlue = cursors[0]->backBlue;
368
369 pCursor->id = cid;
370
371 /* security creation/labeling check */
372 rc = XaceHook(XACE_RESOURCE_ACCESS2, client, cid, RT_CURSOR((RESTYPE)5), pCursor,
373 RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3));
374 if (rc != Success0) {
375 dixFiniPrivates(pCursor, PRIVATE_CURSOR)_dixFiniPrivates((pCursor)->devPrivates,PRIVATE_CURSOR);
376 free(pCursor);
377 return rc;
378 }
379
380 /*
381 * Fill in the AnimCurRec
382 */
383 animCursorBits.refcnt++;
384 ac = GetAnimCur(pCursor)((AnimCurPtr) ((((char *)(pCursor) + (sizeof(CursorRec) + dixPrivatesSize
(PRIVATE_CURSOR))))))
;
385 ac->nelt = ncursor;
386 ac->elts = (AnimCurElt *) (ac + 1);
387
388 for (i = 0; i < ncursor; i++) {
389 ac->elts[i].pCursor = RefCursor(cursors[i]);
390 ac->elts[i].delay = deltas[i];
391 }
392
393 *ppCursor = pCursor;
394 return Success0;
395}