Bug Summary

File:WidgetNode.c
Location:line 132, column 47
Description:Access to field 'resource_name' results in a dereference of a null pointer (loaded from variable 'childres')

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
25*/
26
27/*
28 * Author: Jim Fulton, MIT X Consortium
29 */
30
31
32
33#ifdef HAVE_CONFIG_H1
34#include <config.h>
35#endif
36#include <stdio.h>
37#include <stdlib.h>
38#include <X11/Xos.h>
39#include <X11/IntrinsicP.h>
40#include <X11/Xmu/CharSet.h>
41#include <X11/Xmu/WidgetNode.h>
42
43/*
44 * Prototypes
45 */
46static char *binsearch(char*, char*, int, int,
47 int (*__compar)(_Xconstconst void*, _Xconstconst void*));
48static int compare_resource_entries(_Xconstconst void *a, _Xconstconst void *b);
49static XmuWidgetNode *find_resource(XmuWidgetNode*, char*, Boolint);
50static void mark_resource_owner(XmuWidgetNode*);
51/*
52 * Implementation
53 */
54static char *
55binsearch(char *key, char *base, int nelems, int elemsize,
56 int compar(_Xconstconst void*, _Xconstconst void*))
57 /*
58 * key - template of object to find
59 * base - beginning of array
60 * nelems - number of elements in array
61 * elemsize - sizeof an element
62 * compar - qsort-style compare function
63 */
64{
65 int lower = 0, upper = nelems - 1;
66
67 while (lower <= upper) {
68 int middle = (lower + upper) / 2;
69 char *p = base + middle * elemsize;
70 int res = (*compar) (p, key);
71
72 if (res < 0) {
73 lower = middle + 1;
74 } else if (res == 0) {
75 return p;
76 } else {
77 upper = middle - 1;
78 }
79 }
80
81 return NULL((void*)0);
82}
83
84
85static int
86compare_resource_entries(register _Xconstconst void *a,
87 register _Xconstconst void *b)
88{
89 return strcmp (((_Xconstconst XtResource *)a)->resource_name,
90 ((_Xconstconst XtResource *)b)->resource_name);
91}
92
93
94static XmuWidgetNode *
95find_resource(XmuWidgetNode *node, char *name, Boolint cons)
96{
97 register XmuWidgetNode *sup;
98 XtResource res;
99
100#define reslist ((char *) (cons ? sup->constraints : sup->resources))
101#define nreslist (int) (cons ? sup->nconstraints : sup->nresources)
102
103 res.resource_name = name;
104 for (sup = node->superclass;
105 sup && (XtResourceList) binsearch ((char *) &res,
106 reslist, nreslist,
107 sizeof(XtResource),
108 compare_resource_entries);
109 node = sup, sup = sup->superclass) ;
110
111#undef reslist
112#undef nreslist
113
114 return node;
115}
116
117
118static void
119mark_resource_owner(register XmuWidgetNode *node)
120{
121 register Cardinal i;
122 XtResourceList childres;
123
124 childres = node->resources;
125 for (i = 0; i < node->nresources; i++, childres++) {
15
Loop condition is false. Execution continues on line 130
126 node->resourcewn[i] = find_resource (node, childres->resource_name,
127 False0);
128 }
129
130 childres = node->constraints;
16
Null pointer value stored to 'childres'
131 for (i = 0; i < node->nconstraints; i++, childres++) {
17
Loop condition is true. Entering loop body
132 node->constraintwn[i] = find_resource (node, childres->resource_name,
18
Access to field 'resource_name' results in a dereference of a null pointer (loaded from variable 'childres')
133 True1);
134 }
135}
136
137
138/*
139 * Public Interfaces
140 */
141
142void
143XmuWnInitializeNodes(XmuWidgetNode *nodearray, int nnodes)
144{
145 int i;
146 XmuWidgetNode *wn;
147
148 /*
149 * Assume that the node array is in alphabetic order, so we need to
150 * search backwards to make sure that the children are listed forward.
151 */
152 for (i = nnodes - 1, wn = nodearray + (nnodes - 1); i >= 0; i--, wn--) {
153 WidgetClass superclass = XmuWnSuperclass(wn)((((wn)->widget_class_ptr[0]))->core_class.superclass);
154 int j;
155 XmuWidgetNode *swn;
156 int lablen = strlen (wn->label);
157 int namelen = strlen (XmuWnClassname(wn)(((wn)->widget_class_ptr[0])->core_class.class_name));
158
159 wn->lowered_label = XtMalloc (lablen + namelen + 2);
160#if 0
161 /* XtMalloc exits if failed */
162 if (!wn->lowered_label) {
163 fprintf (stderr__stderrp,
164 "%s: unable to allocate %d bytes for widget name\n",
165 "XmuWnInitializeNodes", lablen + namelen + 2);
166 exit (1);
167 }
168#endif
169 wn->lowered_classname = wn->lowered_label + (lablen + 1);
170 XmuCopyISOLatin1Lowered (wn->lowered_label, wn->label);
171 XmuCopyISOLatin1Lowered (wn->lowered_classname, XmuWnClassname(wn)(((wn)->widget_class_ptr[0])->core_class.class_name));
172 wn->superclass = NULL((void*)0);
173 wn->have_resources = False0;
174 wn->resources = NULL((void*)0);
175 wn->resourcewn = NULL((void*)0);
176 wn->nresources = 0;
177 wn->constraints = NULL((void*)0);
178 wn->constraintwn = NULL((void*)0);
179 wn->nconstraints = 0;
180 wn->data = (XtPointer) NULL((void*)0);
181
182 /*
183 * walk up the superclass chain
184 */
185 while (superclass) {
186 for (j = 0, swn = nodearray; j < nnodes; j++, swn++) {
187 if (superclass == XmuWnClass(swn)((swn)->widget_class_ptr[0])) {
188 wn->superclass = swn;
189 goto done; /* stupid C language */
190 }
191 }
192 /*
193 * Hmm, we have a hidden superclass (such as in core in R4); just
194 * ignore it and keep on walking
195 */
196 superclass = superclass->core_class.superclass;
197 }
198 done:
199 if (wn->superclass) {
200 wn->siblings = wn->superclass->children;
201 wn->superclass->children = wn;
202 }
203 }
204
205 return;
206}
207
208
209void
210XmuWnFetchResources(XmuWidgetNode *node, Widget toplevel,
211 XmuWidgetNode *topnode)
212{
213 Widget dummy;
214 XmuWidgetNode *wn;
215
216 if (node->have_resources) return;
1
Taking false branch
217
218 dummy = XtCreateWidget (node->label, XmuWnClass(node)((node)->widget_class_ptr[0]), toplevel,
219 NULL((void*)0), 0);
220 if (dummy) XtDestroyWidget (dummy);
2
Assuming 'dummy' is null
3
Taking false branch
221
222
223 /*
224 * walk up tree geting resources; since we've instantiated the widget,
225 * we know that all of our superclasses have been initialized
226 */
227 for (wn = node; wn && !wn->have_resources; wn = wn->superclass) {
4
Loop condition is true. Entering loop body
228 XtGetResourceList (XmuWnClass(wn)((wn)->widget_class_ptr[0]), &wn->resources, &wn->nresources);
229 if (wn->resources) {
5
Taking false branch
230 qsort ((char *) wn->resources, wn->nresources,
231 sizeof(XtResource), compare_resource_entries);
232 }
233 wn->resourcewn = (XmuWidgetNode **) XtCalloc (wn->nresources,
234 sizeof (XmuWidgetNode *));
235 if (!wn->resourcewn) {
6
Taking false branch
236 fprintf (stderr__stderrp,
237 "%s: unable to calloc %d %ld byte widget node ptrs\n",
238 "XmuWnFetchResources", wn->nresources,
239 (unsigned long)sizeof (XmuWidgetNode *));
240 exit (1);
241 }
242
243 XtGetConstraintResourceList (XmuWnClass(wn)((wn)->widget_class_ptr[0]), &wn->constraints,
7
Value assigned to field 'constraints'
244 &wn->nconstraints);
245 if (wn->constraints) {
8
Assuming pointer value is null
9
Taking false branch
246 qsort ((char *) wn->constraints, wn->nconstraints,
247 sizeof(XtResource), compare_resource_entries);
248 }
249 wn->constraintwn = (XmuWidgetNode **)
250 XtCalloc (wn->nconstraints, sizeof (XmuWidgetNode *));
251 if (!wn->constraintwn) {
10
Taking false branch
252 fprintf (stderr__stderrp,
253 "%s: unable to calloc %d %ld byte widget node ptrs\n",
254 "XmuWnFetchResources", wn->nconstraints,
255 (unsigned long)sizeof (XmuWidgetNode *));
256 exit (1);
257 }
258
259 wn->have_resources = True1;
260 if (wn == topnode) break;
11
Assuming 'wn' is not equal to 'topnode'
12
Taking false branch
261 }
262
263
264 /*
265 * Walk up tree removing all resources that appear in superclass; we can
266 * mash the resource list in place since it was copied out of widget.
267 */
268 for (wn = node; wn; wn = wn->superclass) {
13
Loop condition is true. Entering loop body
269 mark_resource_owner (wn);
14
Calling 'mark_resource_owner'
270 if (wn == topnode) break;
271 }
272
273 return;
274}
275
276
277int
278XmuWnCountOwnedResources(XmuWidgetNode *node, XmuWidgetNode *ownernode,
279 Boolint cons)
280{
281 register int i;
282 XmuWidgetNode **wn = (cons ? node->constraintwn : node->resourcewn);
283 int nmatches = 0;
284
285 for (i = (cons ? node->nconstraints : node->nresources); i > 0; i--, wn++)
286 if (*wn == ownernode) nmatches++;
287 return nmatches;
288}
289
290
291XmuWidgetNode *
292XmuWnNameToNode(XmuWidgetNode *nodelist, int nnodes, _Xconstconst char *name)
293{
294 int i;
295 XmuWidgetNode *wn;
296 char tmp[1024];
297
298 XmuNCopyISOLatin1Lowered(tmp, name, sizeof(tmp));
299 for (i = 0, wn = nodelist; i < nnodes; i++, wn++) {
300 if (strcmp (tmp, wn->lowered_label) == 0 ||
301 strcmp (tmp, wn->lowered_classname) == 0) {
302 return wn;
303 }
304 }
305 return NULL((void*)0);
306}