Bug Summary

File:XListDev.c
Location:line 164, column 47
Description:The right operand of '+' is a garbage value

Annotated Source Code

1/************************************************************
2
3Copyright 1989, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
26
27 All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Hewlett-Packard not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45********************************************************/
46
47/***********************************************************************
48 *
49 * XListInputDevices - Request the server to return a list of
50 * available input devices.
51 *
52 */
53#ifdef HAVE_CONFIG_H1
54#include <config.h>
55#endif
56
57#include <X11/extensions/XI.h>
58#include <X11/extensions/XIproto.h>
59#include <X11/Xlibint.h>
60#include <X11/extensions/XInput.h>
61#include <X11/extensions/extutil.h>
62#include "XIint.h"
63#include <limits.h>
64
65/* Calculate length field to a multiples of sizeof(XID). XIDs are typedefs
66 * to ulong and thus may be 8 bytes on some platforms. This can trigger a
67 * SIGBUS if a class ends up not being 8-aligned (e.g. after XAxisInfo).
68 */
69static int pad_to_xid(int base_size)
70{
71 int padsize = sizeof(XID);
72
73 return ((base_size + padsize - 1)/padsize) * padsize;
74}
75
76static size_t
77SizeClassInfo(xAnyClassPtr *any, int num_classes)
78{
79 int size = 0;
80 int j;
81 for (j = 0; j < num_classes; j++) {
82 switch ((*any)->class) {
83 case KeyClass0:
84 size += pad_to_xid(sizeof(XKeyInfo));
85 break;
86 case ButtonClass1:
87 size += pad_to_xid(sizeof(XButtonInfo));
88 break;
89 case ValuatorClass2:
90 {
91 xValuatorInfoPtr v;
92
93 v = (xValuatorInfoPtr) *any;
94 size += pad_to_xid(sizeof(XValuatorInfo) +
95 (v->num_axes * sizeof(XAxisInfo)));
96 break;
97 }
98 default:
99 break;
100 }
101 *any = (xAnyClassPtr) ((char *)(*any) + (*any)->length);
102 }
103
104 return size;
105}
106
107static void
108ParseClassInfo(xAnyClassPtr *any, XAnyClassPtr *Any, int num_classes)
109{
110 int j;
111
112 for (j = 0; j < num_classes; j++) {
26
Assuming 'j' is < 'num_classes'
27
Loop condition is true. Entering loop body
113 switch ((*any)->class) {
28
Control jumps to the 'default' case at line 160
114 case KeyClass0:
115 {
116 XKeyInfoPtr K = (XKeyInfoPtr) *Any;
117 xKeyInfoPtr k = (xKeyInfoPtr) *any;
118
119 K->class = KeyClass0;
120 K->length = pad_to_xid(sizeof(XKeyInfo));
121 K->min_keycode = k->min_keycode;
122 K->max_keycode = k->max_keycode;
123 K->num_keys = k->num_keys;
124 break;
125 }
126 case ButtonClass1:
127 {
128 XButtonInfoPtr B = (XButtonInfoPtr) *Any;
129 xButtonInfoPtr b = (xButtonInfoPtr) *any;
130
131 B->class = ButtonClass1;
132 B->length = pad_to_xid(sizeof(XButtonInfo));
133 B->num_buttons = b->num_buttons;
134 break;
135 }
136 case ValuatorClass2:
137 {
138 int k;
139 XValuatorInfoPtr V = (XValuatorInfoPtr) *Any;
140 xValuatorInfoPtr v = (xValuatorInfoPtr) *any;
141 XAxisInfoPtr A;
142 xAxisInfoPtr a;
143
144 V->class = ValuatorClass2;
145 V->length = pad_to_xid(sizeof(XValuatorInfo) +
146 (v->num_axes * sizeof(XAxisInfo)));
147 V->num_axes = v->num_axes;
148 V->motion_buffer = v->motion_buffer_size;
149 V->mode = v->mode;
150 A = (XAxisInfoPtr) ((char *)V + sizeof(XValuatorInfo));
151 V->axes = A;
152 a = (xAxisInfoPtr) ((char *)(*any) + sizeof(xValuatorInfo));
153 for (k = 0; k < (int)v->num_axes; k++, a++, A++) {
154 A->min_value = a->min_value;
155 A->max_value = a->max_value;
156 A->resolution = a->resolution;
157 }
158 break;
159 }
160 default:
161 break;
29
Execution continues on line 163
162 }
163 *any = (xAnyClassPtr) ((char *)(*any) + (*any)->length);
164 *Any = (XAnyClassPtr) ((char *)(*Any) + (*Any)->length);
30
The right operand of '+' is a garbage value
165 }
166}
167
168XDeviceInfo *
169XListInputDevices(
170 register Display *dpy,
171 int *ndevices)
172{
173 size_t size;
174 xListInputDevicesReq *req;
175 xListInputDevicesReply rep;
176 xDeviceInfo *list, *slist = NULL((void*)0);
177 XDeviceInfo *sclist = NULL((void*)0);
178 XDeviceInfo *clist = NULL((void*)0);
179 xAnyClassPtr any, sav_any;
180 XAnyClassPtr Any;
181 unsigned char *nptr, *Nptr;
182 int i;
183 unsigned long rlen;
184 XExtDisplayInfo *info = XInput_find_display(dpy);
185
186 LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display
)(dpy)
;
187 if (_XiCheckExtInit(dpy, XInput_Initial_Release1, info) == -1)
1
Taking false branch
188 return ((XDeviceInfo *) NULL((void*)0));
189
190 GetReq(ListInputDevices, req)req = (xListInputDevicesReq *) _XGetRequest(dpy, 2, 4);
191 req->reqType = info->codes->major_opcode;
192 req->ReqType = X_ListInputDevices2;
193
194 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse0)) {
2
Taking false branch
195 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
196 SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy);
197 return (XDeviceInfo *) NULL((void*)0);
198 }
199
200 if ((*ndevices = rep.ndevices)) { /* at least 1 input device */
3
Assuming is non-zero
4
Taking true branch
201 size = *ndevices * sizeof(XDeviceInfo);
202 if (rep.length < (INT_MAX2147483647 >> 2)) {
5
Taking true branch
203 rlen = rep.length << 2; /* multiply length by 4 */
204 slist = list = Xmalloc(rlen)malloc(((rlen) == 0 ? 1 : (rlen)));
205 }
206 if (!slist) {
6
Assuming 'slist' is non-null
7
Taking false branch
207 _XEatDataWords(dpy, rep.length);
208 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
209 SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy);
210 return (XDeviceInfo *) NULL((void*)0);
211 }
212 _XRead(dpy, (char *)list, rlen);
213
214 any = (xAnyClassPtr) ((char *)list + (*ndevices * sizeof(xDeviceInfo)));
215 sav_any = any;
216 for (i = 0; i < *ndevices; i++, list++) {
8
Loop condition is true. Entering loop body
9
Loop condition is true. Entering loop body
10
Loop condition is true. Entering loop body
11
Loop condition is false. Execution continues on line 220
217 size += SizeClassInfo(&any, (int)list->num_classes);
218 }
219
220 Nptr = ((unsigned char *)list) + rlen + 1;
221 for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) {
12
Loop condition is true. Entering loop body
14
Loop condition is true. Entering loop body
16
Loop condition is true. Entering loop body
18
Loop condition is false. Execution continues on line 228
222 size += *nptr + 1;
223 nptr += (*nptr + 1);
224 if (nptr > Nptr)
13
Taking false branch
15
Taking false branch
17
Taking false branch
225 goto out;
226 }
227
228 clist = (XDeviceInfoPtr) Xmalloc(size)malloc(((size) == 0 ? 1 : (size)));
19
Within the expansion of the macro 'Xmalloc':
a
Assuming 'size' is not equal to 0
b
Uninitialized value stored to field 'length'
229 if (!clist) {
20
Assuming 'clist' is non-null
21
Taking false branch
230 XFree((char *)slist);
231 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
232 SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy);
233 return (XDeviceInfo *) NULL((void*)0);
234 }
235 sclist = clist;
236 Any = (XAnyClassPtr) ((char *)clist +
237 (*ndevices * sizeof(XDeviceInfo)));
238 list = slist;
239 any = sav_any;
240 for (i = 0; i < *ndevices; i++, list++, clist++) {
22
Loop condition is true. Entering loop body
23
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
241 clist->type = list->type;
242 clist->id = list->id;
243 clist->use = list->use;
244 clist->num_classes = list->num_classes;
245 clist->inputclassinfo = Any;
246
247 ParseClassInfo(&any, &Any, (int)list->num_classes);
25
Calling 'ParseClassInfo'
248 }
249
250 clist = sclist;
251 nptr = (unsigned char *)any;
252 Nptr = (unsigned char *)Any;
253 for (i = 0; i < *ndevices; i++, clist++) {
254 clist->name = (char *)Nptr;
255 memcpy(Nptr, nptr + 1, *nptr)__builtin___memcpy_chk (Nptr, nptr + 1, *nptr, __builtin_object_size
(Nptr, 0))
;
256 Nptr += (*nptr);
257 *Nptr++ = '\0';
258 nptr += (*nptr + 1);
259 }
260 }
261
262 out:
263 XFree((char *)slist);
264 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
265 SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy);
266 return (sclist);
267}
268
269/***********************************************************************
270 *
271 * Free the list of input devices.
272 *
273 */
274
275void
276XFreeDeviceList(XDeviceInfo *list)
277{
278 if (list != NULL((void*)0)) {
279 XFree((char *)list);
280 }
281}