Bug Summary

File:alias.c
Location:line 267, column 14
Description:Access to field 'key_aliases' results in a dereference of a null pointer (loaded from field 'names')

Annotated Source Code

1/************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27#include "xkbcomp.h"
28#include "misc.h"
29#include "alias.h"
30#include "keycodes.h"
31
32#include <X11/extensions/XKBgeom.h>
33
34static void
35HandleCollision(AliasInfo * old, AliasInfo * new)
36{
37 if (strncmp(new->real, old->real, XkbKeyNameLength4) == 0)
38 {
39 if (((new->def.fileID == old->def.fileID) && (warningLevel > 0)) ||
40 (warningLevel > 9))
41 {
42 WARN2uWarning("Alias of %s for %s declared more than once\n",
43 XkbKeyNameText(new->alias, XkbMessage3),
44 XkbKeyNameText(new->real, XkbMessage3));
45 ACTIONuAction("First definition ignored\n");
46 }
47 }
48 else
49 {
50 char *use, *ignore;
51 if (new->def.merge == MergeAugment1)
52 {
53 use = old->real;
54 ignore = new->real;
55 }
56 else
57 {
58 use = new->real;
59 ignore = old->real;
60 }
61 if (((old->def.fileID == new->def.fileID) && (warningLevel > 0)) ||
62 (warningLevel > 9))
63 {
64 WARN1uWarning("Multiple definitions for alias %s\n",
65 XkbKeyNameText(old->alias, XkbMessage3));
66 ACTION2uAction("Using %s, ignoring %s\n",
67 XkbKeyNameText(use, XkbMessage3),
68 XkbKeyNameText(ignore, XkbMessage3));
69 }
70 if (use != old->real)
71 memcpy(old->real, use, XkbKeyNameLength4);
72 }
73 old->def.fileID = new->def.fileID;
74 old->def.merge = new->def.merge;
75 return;
76}
77
78static void
79InitAliasInfo(AliasInfo * info,
80 unsigned merge, unsigned file_id, char *alias, char *real)
81{
82 bzero(info, sizeof(AliasInfo))memset(info,0,sizeof(AliasInfo));
83 info->def.merge = merge;
84 info->def.fileID = file_id;
85 strncpy(info->alias, alias, XkbKeyNameLength4);
86 strncpy(info->real, real, XkbKeyNameLength4);
87 return;
88}
89
90int
91HandleAliasDef(KeyAliasDef * def,
92 unsigned merge, unsigned file_id, AliasInfo ** info_in)
93{
94 AliasInfo *info;
95
96 for (info = *info_in; info != NULL((void*)0); info = (AliasInfo *) info->def.next)
97 {
98 if (strncmp(info->alias, def->alias, XkbKeyNameLength4) == 0)
99 {
100 AliasInfo new;
101 InitAliasInfo(&new, merge, file_id, def->alias, def->real);
102 HandleCollision(info, &new);
103 return True1;
104 }
105 }
106 info = uTypedCalloc(1, AliasInfo)((AliasInfo *)uCalloc((unsigned)1,(unsigned)sizeof(AliasInfo)
))
;
107 if (info == NULL((void*)0))
108 {
109 WSGOuInternalError("Allocation failure in HandleAliasDef\n");
110 return False0;
111 }
112 info->def.fileID = file_id;
113 info->def.merge = merge;
114 info->def.next = (CommonInfo *) * info_in;
115 memcpy(info->alias, def->alias, XkbKeyNameLength4);
116 memcpy(info->real, def->real, XkbKeyNameLength4);
117 *info_in = (AliasInfo *) AddCommonInfo(&(*info_in)->def, &info->def);
118 return True1;
119}
120
121void
122ClearAliases(AliasInfo ** info_in)
123{
124 if ((info_in) && (*info_in))
125 ClearCommonInfo(&(*info_in)->def);
126 return;
127}
128
129Boolint
130MergeAliases(AliasInfo ** into, AliasInfo ** merge, unsigned how_merge)
131{
132 AliasInfo *tmp;
133 KeyAliasDef def;
134
135 if ((*merge) == NULL((void*)0))
136 return True1;
137 if ((*into) == NULL((void*)0))
138 {
139 *into = *merge;
140 *merge = NULL((void*)0);
141 return True1;
142 }
143 bzero((char *) &def, sizeof(KeyAliasDef))memset((char *) &def,0,sizeof(KeyAliasDef));
144 for (tmp = *merge; tmp != NULL((void*)0); tmp = (AliasInfo *) tmp->def.next)
145 {
146 if (how_merge == MergeDefault0)
147 def.merge = tmp->def.merge;
148 else
149 def.merge = how_merge;
150 memcpy(def.alias, tmp->alias, XkbKeyNameLength4);
151 memcpy(def.real, tmp->real, XkbKeyNameLength4);
152 if (!HandleAliasDef(&def, def.merge, tmp->def.fileID, into))
153 return False0;
154 }
155 return True1;
156}
157
158int
159ApplyAliases(XkbDescPtr xkb, Boolint toGeom, AliasInfo ** info_in)
160{
161 register int i;
162 XkbKeyAliasPtr old, a;
163 AliasInfo *info;
164 int nNew, nOld;
165 Statusint status;
166
167 if (*info_in == NULL((void*)0))
1
Taking false branch
168 return True1;
169 if (toGeom)
2
Assuming 'toGeom' is 0
3
Taking false branch
170 {
171 nOld = (xkb->geom ? xkb->geom->num_key_aliases : 0);
172 old = (xkb->geom ? xkb->geom->key_aliases : NULL((void*)0));
173 }
174 else
175 {
176 nOld = (xkb->names ? xkb->names->num_key_aliases : 0);
4
'?' condition is false
177 old = (xkb->names ? xkb->names->key_aliases : NULL((void*)0));
5
'?' condition is false
178 }
179 for (nNew = 0, info = *info_in; info != NULL((void*)0);
6
Loop condition is true. Entering loop body
10
Assuming 'info' is equal to null
11
Loop condition is false. Execution continues on line 229
180 info = (AliasInfo *) info->def.next)
181 {
182 unsigned long lname;
183 unsigned int kc;
184
185 lname = KeyNameToLong(info->real)((((unsigned long)info->real[0])<<24)|(((unsigned long
)info->real[1])<<16)|(((unsigned long)info->real[
2])<<8)|info->real[3])
;
186 if (!FindNamedKey(xkb, lname, &kc, False0, CreateKeyNames(xkb)((xkb)->flags&(1L << 0)), 0))
7
Taking false branch
187 {
188 if (warningLevel > 4)
189 {
190 WARN2uWarning("Attempt to alias %s to non-existent key %s\n",
191 XkbKeyNameText(info->alias, XkbMessage3),
192 XkbKeyNameText(info->real, XkbMessage3));
193 ACTIONuAction("Ignored\n");
194 }
195 info->alias[0] = '\0';
196 continue;
197 }
198 lname = KeyNameToLong(info->alias)((((unsigned long)info->alias[0])<<24)|(((unsigned long
)info->alias[1])<<16)|(((unsigned long)info->alias
[2])<<8)|info->alias[3])
;
199 if (FindNamedKey(xkb, lname, &kc, False0, False0, 0))
8
Taking false branch
200 {
201 if (warningLevel > 4)
202 {
203 WARNuWarning("Attempt to create alias with the name of a real key\n");
204 ACTION2uAction("Alias \"%s = %s\" ignored\n",
205 XkbKeyNameText(info->alias, XkbMessage3),
206 XkbKeyNameText(info->real, XkbMessage3));
207 }
208 info->alias[0] = '\0';
209 continue;
210 }
211 nNew++;
212 if (old)
9
Taking false branch
213 {
214 for (i = 0, a = old; i < nOld; i++, a++)
215 {
216 if (strncmp(a->alias, info->alias, XkbKeyNameLength4) == 0)
217 {
218 AliasInfo oldai;
219 InitAliasInfo(&oldai, MergeAugment1, 0, a->alias, a->real);
220 HandleCollision(&oldai, info);
221 memcpy(oldai.real, a->real, XkbKeyNameLength4);
222 info->alias[0] = '\0';
223 nNew--;
224 break;
225 }
226 }
227 }
228 }
229 if (nNew == 0)
12
Taking false branch
230 {
231 ClearCommonInfo(&(*info_in)->def);
232 *info_in = NULL((void*)0);
233 return True1;
234 }
235 status = Success0;
236 if (toGeom)
13
Taking false branch
237 {
238 if (!xkb->geom)
239 {
240 XkbGeometrySizesRec sizes;
241 bzero((char *) &sizes, sizeof(XkbGeometrySizesRec))memset((char *) &sizes,0,sizeof(XkbGeometrySizesRec));
242 sizes.which = XkbGeomKeyAliasesMask(1<<5);
243 sizes.num_key_aliases = nOld + nNew;
244 status = XkbAllocGeometry(xkb, &sizes);
245 }
246 else
247 {
248 status = XkbAllocGeomKeyAliases(xkb->geom, nOld + nNew);
249 }
250 if (xkb->geom)
251 old = xkb->geom->key_aliases;
252 }
253 else
254 {
255 status = XkbAllocNames(xkb, XkbKeyAliasesMask(1<<10), 0, nOld + nNew);
256 if (xkb->names)
14
Taking false branch
257 old = xkb->names->key_aliases;
258 }
259 if (status != Success0)
15
Assuming 'status' is equal to 0
16
Taking false branch
260 {
261 WSGOuInternalError("Allocation failure in ApplyAliases\n");
262 return False0;
263 }
264 if (toGeom)
17
Taking false branch
265 a = &xkb->geom->key_aliases[nOld];
266 else
267 a = &xkb->names->key_aliases[nOld];
18
Access to field 'key_aliases' results in a dereference of a null pointer (loaded from field 'names')
268 for (info = *info_in; info != NULL((void*)0); info = (AliasInfo *) info->def.next)
269 {
270 if (info->alias[0] != '\0')
271 {
272 strncpy(a->alias, info->alias, XkbKeyNameLength4);
273 strncpy(a->real, info->real, XkbKeyNameLength4);
274 a++;
275 }
276 }
277#ifdef DEBUG
278 if ((a - old) != (nOld + nNew))
279 {
280 WSGO2uInternalError("Expected %d aliases total but created %d\n", nOld + nNew,
281 (int)(a - old));
282 }
283#endif
284 if (toGeom)
285 xkb->geom->num_key_aliases += nNew;
286 ClearCommonInfo(&(*info_in)->def);
287 *info_in = NULL((void*)0);
288 return True1;
289}