Bug Summary

File:src/Convert.c
Location:line 410, column 22
Description:Dereference of null pointer

Annotated Source Code

1/***********************************************************
2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3
4Permission is hereby granted, free of charge, to any person obtaining a
5copy of this software and associated documentation files (the "Software"),
6to deal in the Software without restriction, including without limitation
7the rights to use, copy, modify, merge, publish, distribute, sublicense,
8and/or sell copies of the Software, and to permit persons to whom the
9Software is furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice (including the next
12paragraph) shall be included in all copies or substantial portions of the
13Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21DEALINGS IN THE SOFTWARE.
22
23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24
25 All Rights Reserved
26
27Permission to use, copy, modify, and distribute this software and its
28documentation for any purpose and without fee is hereby granted,
29provided that the above copyright notice appear in all copies and that
30both that copyright notice and this permission notice appear in
31supporting documentation, and that the name of Digital not be
32used in advertising or publicity pertaining to distribution of the
33software without specific, written prior permission.
34
35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41SOFTWARE.
42
43******************************************************************/
44
45/*
46
47Copyright 1987, 1988, 1998 The Open Group
48
49Permission to use, copy, modify, distribute, and sell this software and its
50documentation for any purpose is hereby granted without fee, provided that
51the above copyright notice appear in all copies and that both that
52copyright notice and this permission notice appear in supporting
53documentation.
54
55The above copyright notice and this permission notice shall be included in
56all copies or substantial portions of the Software.
57
58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
65Except as contained in this notice, the name of The Open Group shall not be
66used in advertising or otherwise to promote the sale, use or other dealings
67in this Software without prior written authorization from The Open Group.
68
69*/
70
71#ifdef HAVE_CONFIG_H1
72#include <config.h>
73#endif
74#include "IntrinsicI.h"
75#include "StringDefs.h"
76#include "Intrinsic.h"
77
78/* Conversion procedure hash table */
79
80#define CONVERTHASHSIZE((unsigned)256) ((unsigned)256)
81#define CONVERTHASHMASK255 255
82#define ProcHash(from_type, to_type)(2 * (from_type) + to_type) (2 * (from_type) + to_type)
83
84typedef struct _ConverterRec *ConverterPtr;
85typedef struct _ConverterRec {
86 ConverterPtr next;
87 XrmRepresentation from, to;
88 XtTypeConverter converter;
89 XtDestructor destructor;
90 unsigned short num_args;
91 unsigned int do_ref_count:1;
92 unsigned int new_style:1;
93 unsigned int global:1;
94 char cache_type;
95} ConverterRec;
96
97#define ConvertArgs(p)((XtConvertArgList)((p)+1)) ((XtConvertArgList)((p)+1))
98
99/* used for old-style type converter cache only */
100static Heap globalHeap = {NULL((void*)0), NULL((void*)0), 0};
101
102void _XtSetDefaultConverterTable(
103 ConverterTable *table)
104{
105 register ConverterTable globalConverterTable;
106
107 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
108 globalConverterTable = _XtGetProcessContext()->globalConverterTable;
109
110 *table = (ConverterTable)
111 __XtCalloc(CONVERTHASHSIZE((unsigned)256), (unsigned)sizeof(ConverterPtr));
112 _XtAddDefaultConverters(*table);
113
114 if (globalConverterTable) {
115 ConverterPtr rec;
116 int i;
117 XtCacheType cache_type;
118 for (i = CONVERTHASHSIZE((unsigned)256); --i >= 0; ) {
119 for (rec = *globalConverterTable++; rec; rec = rec->next) {
120 cache_type = rec->cache_type;
121 if (rec->do_ref_count)
122 cache_type |= XtCacheRefCount0x100;
123 _XtTableAddConverter(*table, rec->from, rec->to, rec->converter,
124 ConvertArgs(rec)((XtConvertArgList)((rec)+1)), rec->num_args,
125 rec->new_style, cache_type,
126 rec->destructor, True1);
127 }
128 }
129 }
130 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
131}
132
133void _XtFreeConverterTable(
134 ConverterTable table)
135{
136 register Cardinal i;
137 register ConverterPtr p;
138
139 for (i = 0; i < CONVERTHASHSIZE((unsigned)256); i++) {
140 for (p = table[i]; p; ) {
141 register ConverterPtr next = p->next;
142 XtFree((char*)p);
143 p = next;
144 }
145 }
146 XtFree((char*)table);
147}
148
149/* Data cache hash table */
150
151typedef struct _CacheRec *CachePtr;
152
153typedef struct _CacheRec {
154 CachePtr next;
155 XtPointer tag;
156 int hash;
157 XtTypeConverter converter;
158 unsigned short num_args;
159 unsigned int conversion_succeeded:1;
160 unsigned int has_ext:1;
161 unsigned int is_refcounted:1;
162 unsigned int must_be_freed:1;
163 unsigned int from_is_value:1;
164 unsigned int to_is_value:1;
165 XrmValue from;
166 XrmValue to;
167} CacheRec;
168
169typedef struct _CacheRecExt {
170 CachePtr *prev;
171 XtDestructor destructor;
172 XtPointer closure;
173 long ref_count;
174} CacheRecExt;
175
176#define CEXT(p)((CacheRecExt *)((p)+1)) ((CacheRecExt *)((p)+1))
177#define CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) :
(XrmValue *)((p)+1))
((p)->has_ext ? (XrmValue *)(CEXT(p)((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1))
178
179#define CACHEHASHSIZE256 256
180#define CACHEHASHMASK255 255
181typedef CachePtr CacheHashTable[CACHEHASHSIZE256];
182
183static CacheHashTable cacheHashTable;
184
185void _XtTableAddConverter(
186 ConverterTable table,
187 XrmRepresentation from_type,
188 XrmRepresentation to_type,
189 XtTypeConverter converter,
190 XtConvertArgList convert_args,
191 Cardinal num_args,
192 _XtBooleanint new_style,
193 XtCacheType cache_type,
194 XtDestructor destructor,
195 _XtBooleanint global)
196{
197 register ConverterPtr *pp;
198 register ConverterPtr p;
199 XtConvertArgList args;
200
201 pp= &table[ProcHash(from_type, to_type)(2 * (from_type) + to_type) & CONVERTHASHMASK255];
202 while ((p = *pp) && (p->from != from_type || p->to != to_type))
203 pp = &p->next;
204
205 if (p) {
206 *pp = p->next;
207 XtFree((char *)p);
208 }
209
210 p = (ConverterPtr) __XtMalloc(sizeof(ConverterRec) +
211 sizeof(XtConvertArgRec) * num_args);
212 p->next = *pp;
213 *pp = p;
214 p->from = from_type;
215 p->to = to_type;
216 p->converter = converter;
217 p->destructor = destructor;
218 p->num_args = num_args;
219 p->global = global;
220 args = ConvertArgs(p)((XtConvertArgList)((p)+1));
221 while (num_args--)
222 *args++ = *convert_args++;
223 p->new_style = new_style;
224 p->do_ref_count = False0;
225 if (destructor || (cache_type & 0xff)) {
226 p->cache_type = cache_type & 0xff;
227 if (cache_type & XtCacheRefCount0x100)
228 p->do_ref_count = True1;
229 } else {
230 p->cache_type = XtCacheNone0x001;
231 }
232}
233
234void XtSetTypeConverter(
235 register _Xconstconst char* from_type,
236 register _Xconstconst char* to_type,
237 XtTypeConverter converter,
238 XtConvertArgList convert_args,
239 Cardinal num_args,
240 XtCacheType cache_type,
241 XtDestructor destructor
242 )
243{
244 ProcessContext process;
245 XtAppContext app;
246 XrmRepresentation from;
247 XrmRepresentation to;
248
249 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
250 process = _XtGetProcessContext();
251 app = process->appContextList;
252 from = XrmStringToRepresentation(from_type)XrmStringToQuark(from_type);
253 to = XrmStringToRepresentation(to_type)XrmStringToQuark(to_type);
254
255 if (!process->globalConverterTable) {
256 process->globalConverterTable = (ConverterTable)
257 __XtCalloc(CONVERTHASHSIZE((unsigned)256), (unsigned)sizeof(ConverterPtr));
258 }
259 _XtTableAddConverter(process->globalConverterTable, from, to,
260 converter, convert_args,
261 num_args, True1, cache_type, destructor, True1);
262 while (app) {
263 _XtTableAddConverter(app->converterTable, from, to,
264 converter, convert_args,
265 num_args, True1, cache_type, destructor, True1);
266 app = app->next;
267 }
268 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
269}
270
271void XtAppSetTypeConverter(
272 XtAppContext app,
273 register _Xconstconst char* from_type,
274 register _Xconstconst char* to_type,
275 XtTypeConverter converter,
276 XtConvertArgList convert_args,
277 Cardinal num_args,
278 XtCacheType cache_type,
279 XtDestructor destructor
280 )
281{
282 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
283 _XtTableAddConverter(app->converterTable,
284 XrmStringToRepresentation(from_type)XrmStringToQuark(from_type),
285 XrmStringToRepresentation(to_type)XrmStringToQuark(to_type),
286 converter, convert_args, num_args,
287 True1, cache_type, destructor, False0);
288 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
289}
290
291/* old interface */
292void XtAddConverter(
293 register _Xconstconst char* from_type,
294 register _Xconstconst char* to_type,
295 XtConverter converter,
296 XtConvertArgList convert_args,
297 Cardinal num_args
298 )
299{
300 ProcessContext process;
301 XtAppContext app;
302 XrmRepresentation from;
303 XrmRepresentation to;
304
305 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
306 process = _XtGetProcessContext();
307 app = process->appContextList;
308 from = XrmStringToRepresentation(from_type)XrmStringToQuark(from_type);
309 to = XrmStringToRepresentation(to_type)XrmStringToQuark(to_type);
310
311 if (!process->globalConverterTable) {
312 process->globalConverterTable = (ConverterTable)
313 __XtCalloc(CONVERTHASHSIZE((unsigned)256), (unsigned)sizeof(ConverterPtr));
314 }
315 _XtTableAddConverter(process->globalConverterTable, from, to,
316 (XtTypeConverter)converter, convert_args, num_args,
317 False0, XtCacheAll0x002, (XtDestructor)NULL((void*)0), True1);
318 while (app) {
319 _XtTableAddConverter(app->converterTable, from, to,
320 (XtTypeConverter)converter, convert_args,
321 num_args, False0, XtCacheAll0x002, (XtDestructor)NULL((void*)0),
322 True1);
323 app = app->next;
324 }
325 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
326}
327
328/* old interface */
329void XtAppAddConverter(
330 XtAppContext app,
331 register _Xconstconst char* from_type,
332 register _Xconstconst char* to_type,
333 XtConverter converter,
334 XtConvertArgList convert_args,
335 Cardinal num_args
336 )
337{
338 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
339 _XtTableAddConverter(app->converterTable,
340 XrmStringToRepresentation(from_type)XrmStringToQuark(from_type),
341 XrmStringToRepresentation(to_type)XrmStringToQuark(to_type),
342 (XtTypeConverter)converter, convert_args, num_args,
343 False0, XtCacheAll0x002, (XtDestructor)NULL((void*)0), False0);
344 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
345}
346
347static CachePtr
348CacheEnter(
349 Heap* heap,
350 register XtTypeConverter converter,
351 register XrmValuePtr args,
352 Cardinal num_args,
353 XrmValuePtr from,
354 XrmValuePtr to,
355 Boolean succeeded,
356 register int hash,
357 Boolean do_ref,
358 Boolean do_free,
359 XtDestructor destructor,
360 XtPointer closure)
361{
362 register CachePtr *pHashEntry;
363 register CachePtr p;
364 register Cardinal i;
365
366 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
367 pHashEntry = &cacheHashTable[hash & CACHEHASHMASK255];
368
369 if ((succeeded && destructor) || do_ref) {
18
Taking false branch
370 p = (CachePtr) _XtHeapAlloc(heap, (sizeof(CacheRec) +
371 sizeof(CacheRecExt) +
372 num_args * sizeof(XrmValue)));
373 CEXT(p)((CacheRecExt *)((p)+1))->prev = pHashEntry;
374 CEXT(p)((CacheRecExt *)((p)+1))->destructor = succeeded ? destructor : NULL((void*)0);
375 CEXT(p)((CacheRecExt *)((p)+1))->closure = closure;
376 CEXT(p)((CacheRecExt *)((p)+1))->ref_count = 1;
377 p->has_ext = True1;
378 }
379 else {
380 p = (CachePtr)_XtHeapAlloc(heap, (sizeof(CacheRec) +
381 num_args * sizeof(XrmValue)));
382 p->has_ext = False0;
383 }
384 if (!to->addr)
19
Taking false branch
385 succeeded = False0;
386 p->conversion_succeeded = succeeded;
387 p->is_refcounted = do_ref;
388 p->must_be_freed = do_free;
389 p->next = *pHashEntry;
390 if (p->next && p->next->has_ext)
391 CEXT(p->next)((CacheRecExt *)((p->next)+1))->prev = &p->next;
392
393 *pHashEntry = p;
394 p->tag = (XtPointer)heap;
395 p->hash = hash;
396 p->converter = converter;
397 p->from.size = from->size;
398 if (from->size <= sizeof(p->from.addr)) {
20
Taking true branch
399 p->from_is_value = True1;
400 XtMemmove(&p->from.addr, from->addr, from->size)if ((char *)(&p->from.addr) != (char *)(from->addr)
) { (void) __builtin___memcpy_chk ((char *) (&p->from.
addr), (char *) (from->addr), (int) (from->size), __builtin_object_size
((char *) (&p->from.addr), 0)); }
;
401 } else {
402 p->from_is_value = False0;
403 p->from.addr = (XPointer)_XtHeapAlloc(heap, from->size);
404 (void) memmove((char *)p->from.addr, (char *)from->addr, from->size)__builtin___memmove_chk ((char *)p->from.addr, (char *)from
->addr, from->size, __builtin_object_size ((char *)p->
from.addr, 0))
;
405 }
406 p->num_args = num_args;
407 if (num_args) {
21
Assuming 'num_args' is not equal to 0
22
Taking true branch
408 XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) :
(XrmValue *)((p)+1))
;
409 for (i = 0; i < num_args; i++) {
23
Loop condition is true. Entering loop body
410 pargs[i].size = args[i].size;
24
Dereference of null pointer
411 pargs[i].addr = (XPointer)_XtHeapAlloc(heap, args[i].size);
412 XtMemmove(pargs[i].addr, args[i].addr, args[i].size)if ((char *)(pargs[i].addr) != (char *)(args[i].addr)) { (void
) __builtin___memcpy_chk ((char *) (pargs[i].addr), (char *) (
args[i].addr), (int) (args[i].size), __builtin_object_size ((
char *) (pargs[i].addr), 0)); }
;
413 }
414 }
415 p->to.size = to->size;
416 if (!succeeded) {
417 p->to_is_value = False0;
418 p->to.addr = NULL((void*)0);
419 } else if (to->size <= sizeof(p->to.addr)) {
420 p->to_is_value = True1;
421 XtMemmove(&p->to.addr, to->addr, to->size)if ((char *)(&p->to.addr) != (char *)(to->addr)) { (
void) __builtin___memcpy_chk ((char *) (&p->to.addr), (
char *) (to->addr), (int) (to->size), __builtin_object_size
((char *) (&p->to.addr), 0)); }
;
422 } else {
423 p->to_is_value = False0;
424 p->to.addr = (XPointer)_XtHeapAlloc(heap, to->size);
425 (void) memmove((char *)p->to.addr, (char *)to->addr, to->size)__builtin___memmove_chk ((char *)p->to.addr, (char *)to->
addr, to->size, __builtin_object_size ((char *)p->to.addr
, 0))
;
426 }
427 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
428 return p;
429}
430
431static void FreeCacheRec(
432 XtAppContext app,
433 CachePtr p,
434 CachePtr *prev)
435{
436 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
437 if (p->has_ext) {
438 if (CEXT(p)((CacheRecExt *)((p)+1))->destructor) {
439 Cardinal num_args = p->num_args;
440 XrmValue *args = NULL((void*)0);
441 XrmValue toc;
442 if (num_args)
443 args = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) :
(XrmValue *)((p)+1))
;
444 toc.size = p->to.size;
445 if (p->to_is_value)
446 toc.addr = (XPointer)&p->to.addr;
447 else
448 toc.addr = p->to.addr;
449 (*CEXT(p)((CacheRecExt *)((p)+1))->destructor) (app, &toc, CEXT(p)((CacheRecExt *)((p)+1))->closure, args,
450 &num_args);
451 }
452 *(CEXT(p)((CacheRecExt *)((p)+1))->prev) = p->next;
453 if (p->next && p->next->has_ext)
454 CEXT(p->next)((CacheRecExt *)((p->next)+1))->prev = CEXT(p)((CacheRecExt *)((p)+1))->prev;
455 } else {
456 *prev = p->next;
457 if (p->next && p->next->has_ext)
458 CEXT(p->next)((CacheRecExt *)((p->next)+1))->prev = prev;
459 }
460 if (p->must_be_freed) {
461 register int i;
462 if (!p->from_is_value)
463 XtFree(p->from.addr);
464 if ((i = p->num_args)) {
465 XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) :
(XrmValue *)((p)+1))
;
466 while (i--)
467 XtFree(pargs[i].addr);
468 }
469 if (!p->to_is_value)
470 XtFree(p->to.addr);
471 XtFree((char*)p);
472 }
473 /* else on private heap; will free entire heap later */
474 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
475}
476
477
478void _XtCacheFlushTag(
479 XtAppContext app,
480 XtPointer tag)
481{
482 int i;
483 register CachePtr *prev;
484 register CachePtr rec;
485
486 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
487 for (i = CACHEHASHSIZE256; --i >= 0;) {
488 prev = &cacheHashTable[i];
489 while ((rec = *prev)) {
490 if (rec->tag == tag)
491 FreeCacheRec(app, rec, prev);
492 else
493 prev = &rec->next;
494 }
495 }
496 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
497}
498
499#ifdef DEBUG
500#include <stdio.h>
501
502void _XtConverterCacheStats(void)
503{
504 register Cardinal i;
505 register CachePtr p;
506 register Cardinal entries;
507
508 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
509 for (i = 0; i < CACHEHASHSIZE256; i++) {
510 p = cacheHashTable[i];
511 if (p) {
512 for (entries = 0; p; p = p->next) {
513 entries++;
514 }
515 (void) fprintf(stdout, "Index: %4d Entries: %d\n", i, entries);
516 for (p = cacheHashTable[i]; p; p = p->next) {
517 (void) fprintf(stdout, " Size: %3d Refs: %3d '",
518 p->from.size,
519 p->has_ext ? CEXT(p)((CacheRecExt *)((p)+1))->ref_count : 0);
520 (void) fprintf(stdout, "'\n");
521 }
522 (void) fprintf(stdout, "\n");
523 }
524 }
525 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
526}
527#endif /*DEBUG*/
528
529static Boolean ResourceQuarkToOffset(
530 WidgetClass widget_class,
531 XrmName name,
532 Cardinal *offset)
533{
534 register WidgetClass wc;
535 register Cardinal i;
536 register XrmResourceList res, *resources;
537
538 for (wc = widget_class; wc; wc = wc->core_class.superclass) {
539 resources = (XrmResourceList*) wc->core_class.resources;
540 for (i = 0; i < wc->core_class.num_resources; i++, resources++) {
541 res = *resources;
542 if (res->xrm_name == name) {
543 *offset = -res->xrm_offset - 1;
544 return True1;
545 }
546 } /* for i in resources */
547 } /* for wc in widget classes */
548 (*offset) = 0;
549 return False0;
550}
551
552
553static void ComputeArgs(
554 Widget widget,
555 XtConvertArgList convert_args,
556 Cardinal num_args,
557 XrmValuePtr args)
558{
559 register Cardinal i;
560 Cardinal offset;
561 String params[1];
562 Cardinal num_params = 1;
563 Widget ancestor = NULL((void*)0);
564
565 for (i = 0; i < num_args; i++) {
566 args[i].size = convert_args[i].size;
567 switch (convert_args[i].address_mode) {
568 case XtAddress:
569 args[i].addr = convert_args[i].address_id;
570 break;
571
572 case XtBaseOffset:
573 args[i].addr =
574 (XPointer)((char *)widget + (long)convert_args[i].address_id);
575 break;
576
577 case XtWidgetBaseOffset:
578 if (!ancestor) {
579 if (XtIsWidget(widget)(((Object)(widget))->object.widget_class->core_class.class_inited
& 0x04)
)
580 ancestor = widget;
581 else
582 ancestor = _XtWindowedAncestor(widget);
583 }
584
585 args[i].addr =
586 (XPointer)((char *)ancestor + (long)convert_args[i].address_id);
587 break;
588
589 case XtImmediate:
590 args[i].addr = (XPointer) &(convert_args[i].address_id);
591 break;
592
593 case XtProcedureArg:
594 (*(XtConvertArgProc)convert_args[i].address_id)
595 (widget, &convert_args[i].size, &args[i]);
596 break;
597
598 case XtResourceString:
599 /* Convert in place for next usage */
600 convert_args[i].address_mode = XtResourceQuark;
601 convert_args[i].address_id =
602 (XtPointer)(long)XrmStringToQuark((String)convert_args[i].address_id);
603 /* Fall through */
604
605 case XtResourceQuark:
606 if (! ResourceQuarkToOffset(widget->core.widget_class,
607 (XrmQuark)(long) convert_args[i].address_id, &offset)) {
608 params[0]=
609 XrmQuarkToString((XrmQuark)(long) convert_args[i].address_id);
610 XtAppWarningMsg(XtWidgetToApplicationContext(widget),
611 "invalidResourceName","computeArgs",XtCXtToolkitError,
612 "Cannot find resource name %s as argument to conversion",
613 params,&num_params);
614 offset = 0;
615 }
616 args[i].addr = (XPointer)((char *)widget + offset);
617 break;
618 default:
619 params[0] = XtName(widget);
620 XtAppWarningMsg(XtWidgetToApplicationContext(widget),
621 "invalidAddressMode", "computeArgs", XtCXtToolkitError,
622 "Conversion arguments for widget '%s' contain an unsupported address mode",
623 params,&num_params);
624 args[i].addr = NULL((void*)0);
625 args[i].size = 0;
626 } /* switch */
627 } /* for */
628} /* ComputeArgs */
629
630void XtDirectConvert(
631 XtConverter converter,
632 XrmValuePtr args,
633 Cardinal num_args,
634 register XrmValuePtr from,
635 XrmValuePtr to)
636{
637 register CachePtr p;
638 register int hash;
639 register Cardinal i;
640
641 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
642 /* Try to find cache entry for conversion */
643 hash = ((long) converter >> 2) + from->size + *((char *) from->addr);
644 if (from->size > 1) hash += ((char *) from->addr)[1];
14
Taking false branch
645
646 for (p = cacheHashTable[hash & CACHEHASHMASK255]; p; p = p->next) {
15
Loop condition is false. Execution continues on line 680
647 if ((p->hash == hash)
648 && (p->converter == (XtTypeConverter)converter)
649 && (p->from.size == from->size)
650 && !(p->from_is_value ?
651 XtMemcmp(&p->from.addr, from->addr, from->size)memcmp((char *) (&p->from.addr), (char *) (from->addr
), (int) (from->size))
:
652 memcmp((char *)p->from.addr, (char *)from->addr, from->size))
653 && (p->num_args == num_args)) {
654 if ((i = num_args)) {
655 XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) :
(XrmValue *)((p)+1))
;
656 /* Are all args the same data ? */
657 while (i) {
658 i--; /* do not move to while test, broken compilers */
659 if (pargs[i].size != args[i].size ||
660 XtMemcmp(pargs[i].addr, args[i].addr, args[i].size)memcmp((char *) (pargs[i].addr), (char *) (args[i].addr), (int
) (args[i].size))
) {
661 i++;
662 break;
663 }
664 }
665 }
666 if (!i) {
667 /* Perfect match */
668 to->size = p->to.size;
669 if (p->to_is_value)
670 to->addr = (XPointer)&p->to.addr;
671 else
672 to->addr = p->to.addr;
673 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
674 return;
675 }
676 }
677 }
678
679 /* Didn't find it, call converter procedure and entry result in cache */
680 (*to).size = 0;
681 (*to).addr = NULL((void*)0);
682 (*converter)(args, &num_args, from, to);
683 /* This memory can never be freed since we don't know the Display
684 * or app context from which to compute the persistance */
685 {
686 CacheEnter(&globalHeap, (XtTypeConverter)converter, args, num_args,
16
Passing null pointer value via 3rd parameter 'args'
17
Calling 'CacheEnter'
687 from, to, (to->addr != NULL((void*)0)), hash, False0, False0,
688 (XtDestructor)NULL((void*)0), NULL((void*)0));
689 }
690 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
691}
692
693
694static ConverterPtr GetConverterEntry(
695 XtAppContext app,
696 XtTypeConverter converter)
697{
698 Cardinal entry;
699 register ConverterPtr cP;
700 ConverterTable converterTable;
701
702 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
703 converterTable = app->converterTable;
704 cP = NULL((void*)0);
705 for (entry = 0; (entry < CONVERTHASHSIZE((unsigned)256)) && !cP; entry++) {
706 cP = converterTable[entry];
707 while (cP && (cP->converter != converter)) cP = cP->next;
708 }
709 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
710 return cP;
711}
712
713
714static Boolean
715CallConverter(
716 Display* dpy,
717 XtTypeConverter converter,
718 XrmValuePtr args,
719 Cardinal num_args,
720 register XrmValuePtr from,
721 XrmValuePtr to,
722 XtCacheRef *cache_ref_return,
723 register ConverterPtr cP)
724{
725 CachePtr p;
726 int hash;
727 Cardinal i;
728 Boolean retval;
729
730 if (!cP || ((cP->cache_type == XtCacheNone0x001) && !cP->destructor)) {
731 XtPointer closure;
732 if (cache_ref_return) *cache_ref_return = NULL((void*)0);
733 retval = (*(XtTypeConverter)converter)
734 (dpy, args, &num_args, from, to, &closure);
735 return retval;
736 }
737
738 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
739 /* Try to find cache entry for conversion */
740 hash = ((long)(converter) >> 2) + from->size + *((char *) from->addr);
741 if (from->size > 1) hash += ((char *) from->addr)[1];
742
743 if (cP->cache_type != XtCacheNone0x001) {
744 for (p = cacheHashTable[hash & CACHEHASHMASK255]; p; p = p->next){
745 if ((p->hash == hash)
746 && (p->converter == converter)
747 && (p->from.size == from->size)
748 && !(p->from_is_value ?
749 XtMemcmp(&p->from.addr, from->addr, from->size)memcmp((char *) (&p->from.addr), (char *) (from->addr
), (int) (from->size))
:
750 memcmp((char *)p->from.addr, (char *)from->addr, from->size))
751 && (p->num_args == num_args)) {
752 if ((i = num_args)) {
753 XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) :
(XrmValue *)((p)+1))
;
754 /* Are all args the same data ? */
755 while (i) {
756 i--; /* do not move to while test, broken compilers */
757 if (pargs[i].size != args[i].size ||
758 XtMemcmp(pargs[i].addr, args[i].addr, args[i].size)memcmp((char *) (pargs[i].addr), (char *) (args[i].addr), (int
) (args[i].size))
){
759 i++;
760 break;
761 }
762 }
763 }
764 if (!i) {
765 /* Perfect match */
766 if (p->conversion_succeeded) {
767 if (to->addr) { /* new-style call */
768 if (to->size < p->to.size) {
769 to->size = p->to.size;
770 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
771 return False0;
772 }
773 to->size = p->to.size;
774 if (p->to_is_value) {
775 XtMemmove(to->addr, &p->to.addr,if ((char *)(to->addr) != (char *)(&p->to.addr)) { (
void) __builtin___memcpy_chk ((char *) (to->addr), (char *
) (&p->to.addr), (int) (to->size), __builtin_object_size
((char *) (to->addr), 0)); }
776 to->size)if ((char *)(to->addr) != (char *)(&p->to.addr)) { (
void) __builtin___memcpy_chk ((char *) (to->addr), (char *
) (&p->to.addr), (int) (to->size), __builtin_object_size
((char *) (to->addr), 0)); }
;
777 } else {
778 (void) memmove((char *)to->addr,__builtin___memmove_chk ((char *)to->addr, (char *)p->to
.addr, to->size, __builtin_object_size ((char *)to->addr
, 0))
779 (char *)p->to.addr, to->size)__builtin___memmove_chk ((char *)to->addr, (char *)p->to
.addr, to->size, __builtin_object_size ((char *)to->addr
, 0))
;
780 }
781 } else { /* old-style call */
782 to->size = p->to.size;
783 if (p->to_is_value)
784 to->addr = (XPointer)&p->to.addr;
785 else
786 to->addr = p->to.addr;
787 }
788 }
789 if (p->is_refcounted) {
790 CEXT(p)((CacheRecExt *)((p)+1))->ref_count++;
791 if (cache_ref_return)
792 *cache_ref_return = (XtCacheRef)p;
793 else
794 p->is_refcounted = False0;
795 }
796 else {
797 if (cache_ref_return)
798 *cache_ref_return = NULL((void*)0);
799 }
800 retval = (p->conversion_succeeded);
801 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
802 return retval;
803 }
804 }
805 }
806 }
807
808 /* No cache entry, call converter procedure and enter result in cache */
809 {
810 Heap *heap;
811 XtPointer closure = NULL((void*)0);
812 unsigned int supplied_size = to->size;
813 Boolean do_ref = cP->do_ref_count && cache_ref_return;
814 Boolean do_free = False0;
815 Boolean retval =
816 (*(XtTypeConverter)converter)(dpy, args, &num_args, from, to, &closure);
817
818 if (retval == False0 && supplied_size < to->size) {
819 /* programmer error: caller must allocate sufficient storage */
820 if (cache_ref_return)
821 *cache_ref_return = NULL((void*)0);
822 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
823 return False0;
824 }
825
826 if ((cP->cache_type == XtCacheNone0x001) || do_ref) {
827 heap = NULL((void*)0);
828 do_free = True1;
829 }
830 else if (cP->cache_type == XtCacheByDisplay0x003)
831 heap = &_XtGetPerDisplay(dpy)->heap;
832 else if (cP->global)
833 heap = &globalHeap;
834 else
835 heap = &XtDisplayToApplicationContext(dpy)->heap;
836
837 p = CacheEnter(heap, converter, args, num_args, from, to, retval,
838 hash, do_ref, do_free, cP->destructor, closure);
839 if (do_ref)
840 *cache_ref_return = (XtCacheRef)p;
841 else if (cache_ref_return)
842 *cache_ref_return = NULL((void*)0);
843 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
844 return retval;
845 }
846}
847
848Boolean
849XtCallConverter(
850 Display* dpy,
851 XtTypeConverter converter,
852 XrmValuePtr args,
853 Cardinal num_args,
854 register XrmValuePtr from,
855 XrmValuePtr to,
856 XtCacheRef *cache_ref_return)
857{
858 ConverterPtr cP;
859 Boolean retval;
860 XtAppContext app = XtDisplayToApplicationContext(dpy);
861
862 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
863 if ((cP = GetConverterEntry(app, converter)) == NULL((void*)0)) {
864 XtAppSetTypeConverter(XtDisplayToApplicationContext(dpy),
865 "_XtUnk1", "_XtUnk2",
866 converter, NULL((void*)0), 0,
867 XtCacheAll0x002, NULL((void*)0));
868 cP = GetConverterEntry(app, converter);
869 }
870 retval = CallConverter(dpy, converter, args, num_args, from, to,
871 cache_ref_return, cP);
872 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
873 return retval;
874}
875
876Boolean _XtConvert(
877 Widget widget,
878 register XrmRepresentation from_type,
879 XrmValuePtr from,
880 register XrmRepresentation to_type,
881 register XrmValuePtr to,
882 XtCacheRef *cache_ref_return)
883{
884 XtAppContext app = XtWidgetToApplicationContext(widget);
885 register ConverterPtr p;
886 Cardinal num_args;
887 XrmValue *args;
888
889 /* Look for type converter */
890 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
891 p = app->converterTable[ProcHash(from_type, to_type)(2 * (from_type) + to_type) & CONVERTHASHMASK255];
892 for (; p; p = p->next) {
3
Loop condition is true. Entering loop body
4
Loop condition is true. Entering loop body
5
Loop condition is true. Entering loop body
6
Loop condition is true. Entering loop body
893 if (from_type == p->from && to_type == p->to) {
7
Taking true branch
894 Boolean retval = False0;
895 /* Compute actual arguments from widget and arg descriptor */
896 num_args = p->num_args;
897 if (num_args != 0) {
8
Assuming 'num_args' is equal to 0
9
Taking false branch
898 args = (XrmValue*)
899 ALLOCATE_LOCAL( num_args * sizeof (XrmValue) )__builtin_alloca((int)(num_args * sizeof (XrmValue)));
900 if (!args) _XtAllocError("alloca");
901 ComputeArgs(widget, ConvertArgs(p)((XtConvertArgList)((p)+1)), num_args, args);
902 } else args = NULL((void*)0);
10
Null pointer value stored to 'args'
903 if (p->new_style) {
11
Taking false branch
904 retval =
905 CallConverter(XtDisplayOfObject(widget)((((Object)(widget))->object.widget_class->core_class.class_inited
& 0x04) ? (widget)->core.screen->display : _XtIsHookObject
(widget) ? ((HookObject)(widget))->hooks.screen->display
: _XtWindowedAncestor(widget)->core.screen->display)
,
906 p->converter, args, num_args,
907 from, to, cache_ref_return, p);
908 }
909 else { /* is old-style (non-display) converter */
910 XrmValue tempTo;
911 XtDirectConvert((XtConverter)p->converter, args, num_args,
12
Passing null pointer value via 2nd parameter 'args'
13
Calling 'XtDirectConvert'
912 from, &tempTo);
913 if (cache_ref_return)
914 *cache_ref_return = NULL((void*)0);
915 if (tempTo.addr) {
916 if (to->addr) { /* new-style caller */
917 if (to->size >= tempTo.size) {
918 if (to_type == _XtQString)
919 *(String*)(to->addr) = tempTo.addr;
920 else {
921 XtMemmove(to->addr, tempTo.addr,if ((char *)(to->addr) != (char *)(tempTo.addr)) { (void) __builtin___memcpy_chk
((char *) (to->addr), (char *) (tempTo.addr), (int) (tempTo
.size), __builtin_object_size ((char *) (to->addr), 0)); }
922 tempTo.size)if ((char *)(to->addr) != (char *)(tempTo.addr)) { (void) __builtin___memcpy_chk
((char *) (to->addr), (char *) (tempTo.addr), (int) (tempTo
.size), __builtin_object_size ((char *) (to->addr), 0)); }
;
923 }
924 retval = True1;
925 }
926 to->size = tempTo.size;
927 } else { /* old-style caller */
928 *to = tempTo;
929 retval = True1;
930 }
931 }
932 }
933 if (args) DEALLOCATE_LOCAL( (XtPointer)args )do {} while(0);
934 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
935 return retval;
936 }
937 }
938
939 {
940 String params[2];
941 Cardinal num_params = 2;
942 params[0] = XrmRepresentationToString(from_type)XrmQuarkToString(from_type);
943 params[1] = XrmRepresentationToString(to_type)XrmQuarkToString(to_type);
944 XtAppWarningMsg(app, "typeConversionError", "noConverter", XtCXtToolkitError,
945 "No type converter registered for '%s' to '%s' conversion.",
946 params, &num_params);
947 }
948 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
949 return False0;
950}
951
952void XtConvert(
953 Widget widget,
954 _Xconstconst char* from_type_str,
955 XrmValuePtr from,
956 _Xconstconst char* to_type_str,
957 XrmValuePtr to)
958{
959 XrmQuark from_type, to_type;
960 WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext
(widget) : ((void*)0))
;
961
962 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
963 from_type = XrmStringToRepresentation(from_type_str)XrmStringToQuark(from_type_str);
964 to_type = XrmStringToRepresentation(to_type_str)XrmStringToQuark(to_type_str);
965 if (from_type != to_type) {
1
Taking true branch
966 /* It's not safe to ref count these resources, 'cause we
967 don't know what older clients may have assumed about
968 the resource lifetimes.
969 XtCacheRef ref;
970 */
971 to->addr = NULL((void*)0);
972 to->size = 0;
973 _XtConvert(widget, from_type, from, to_type, to, /*&ref*/ NULL((void*)0));
2
Calling '_XtConvert'
974 /*
975 if (ref) {
976 XtAddCallback( widget, XtNdestroyCallback,
977 XtCallbackReleaseCacheRef, (XtPointer)ref );
978 }
979 */
980 }
981 else
982 (*to) = *from;
983 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
984}
985
986Boolean XtConvertAndStore(
987 Widget object,
988 _Xconstconst char* from_type_str,
989 XrmValuePtr from,
990 _Xconstconst char* to_type_str,
991 XrmValuePtr to)
992{
993 XrmQuark from_type, to_type;
994 WIDGET_TO_APPCON(object)XtAppContext app = (object && _XtProcessLock ? XtWidgetToApplicationContext
(object) : ((void*)0))
;
995
996 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
997 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
998 from_type = XrmStringToRepresentation(from_type_str)XrmStringToQuark(from_type_str);
999 to_type = XrmStringToRepresentation(to_type_str)XrmStringToQuark(to_type_str);
1000 if (from_type != to_type) {
1001 static XtPointer local_valueP = NULL((void*)0);
1002 static Cardinal local_valueS = 128;
1003 XtCacheRef ref;
1004 Boolean local = False0;
1005 do {
1006 if (!to->addr) {
1007 if (!local_valueP)
1008 local_valueP = _XtHeapAlloc(&globalHeap, local_valueS);
1009 to->addr = local_valueP;
1010 to->size = local_valueS;
1011 local = True1;
1012 }
1013 if (!_XtConvert(object, from_type, from, to_type, to, &ref)) {
1014 if (local && (to->size > local_valueS)) {
1015 to->addr =
1016 local_valueP = _XtHeapAlloc(&globalHeap, to->size);
1017 local_valueS = to->size;
1018 continue;
1019 } else {
1020 if (local) {
1021 to->addr = NULL((void*)0);
1022 to->size = 0;
1023 }
1024 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
1025 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
1026 return False0;
1027 }
1028 }
1029 if (ref) {
1030 XtAddCallback( object, XtNdestroyCallback((char*)&XtStrings[169]),
1031 XtCallbackReleaseCacheRef, (XtPointer)ref );
1032 }
1033 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
1034 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
1035 return True1;
1036 } while (local /* && local_valueS < to->size */);
1037 }
1038 if (to->addr) {
1039 if (to->size < from->size) {
1040 to->size = from->size;
1041 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
1042 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
1043 return False0;
1044 }
1045 (void) memmove(to->addr, from->addr, from->size )__builtin___memmove_chk (to->addr, from->addr, from->
size, __builtin_object_size (to->addr, 0))
;
1046 to->size = from->size;
1047 } else /* from_type == to_type */
1048 *to = *from;
1049 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
1050 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
1051 return True1;
1052}
1053
1054void XtAppReleaseCacheRefs(
1055 XtAppContext app,
1056 XtCacheRef *refs)
1057{
1058 register CachePtr *r;
1059 register CachePtr p;
1060
1061 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
1062 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
1063 for (r = (CachePtr*)refs; (p = *r); r++) {
1064 if (p->is_refcounted && --(CEXT(p)((CacheRecExt *)((p)+1))->ref_count) == 0) {
1065 FreeCacheRec(app, p, NULL((void*)0));
1066 }
1067 }
1068 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
1069 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
1070}
1071
1072
1073/* ARGSUSED */
1074void XtCallbackReleaseCacheRefList(
1075 Widget widget, /* unused */
1076 XtPointer closure,
1077 XtPointer call_data) /* unused */
1078{
1079 XtAppReleaseCacheRefs( XtWidgetToApplicationContext(widget),
1080 (XtCacheRef*)closure );
1081 XtFree(closure);
1082}
1083
1084
1085/* ARGSUSED */
1086void XtCallbackReleaseCacheRef(
1087 Widget widget, /* unused */
1088 XtPointer closure,
1089 XtPointer call_data) /* unused */
1090{
1091 XtCacheRef cache_refs[2];
1092 cache_refs[0] = (XtCacheRef)closure;
1093 cache_refs[1] = NULL((void*)0);
1094 XtAppReleaseCacheRefs( XtWidgetToApplicationContext(widget), cache_refs );
1095}