Bug Summary

File:src/Alloc.c
Location:line 149, column 2
Description:Null pointer argument in call to string copy function

Annotated Source Code

1/***********************************************************
2Copyright (c) 1993, 2011, 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/*
72 * X Toolkit Memory Allocation Routines
73 *
74 * Uses Xlib memory management, which is spec'd to be re-entrant.
75 */
76
77#ifdef HAVE_CONFIG_H1
78#include <config.h>
79#endif
80#include "IntrinsicI.h"
81#include "InitialI.h"
82#undef _XBCOPYFUNC
83
84#include <stdlib.h>
85#include <stdio.h>
86#include <stdarg.h>
87
88#define Xmalloc(size)malloc((size)) malloc((size))
89#define Xrealloc(ptr, size)realloc((ptr), (size)) realloc((ptr), (size))
90#define Xcalloc(nelem, elsize)calloc((nelem), (elsize)) calloc((nelem), (elsize))
91#define Xfree(ptr)free(ptr) free(ptr)
92
93#ifdef _XNEEDBCOPYFUNC
94void _XtBcopy(
95 char *src, char *dst,
96 int length)
97{
98 if (src < dst) {
99 dst += length;
100 src += length;
101 while (length--)
102 *--dst = *--src;
103 } else {
104 while (length--)
105 *dst++ = *src++;
106 }
107}
108#endif
109
110void _XtAllocError(
111 String type)
112{
113 Cardinal num_params = 1;
114 if (type == NULL((void*)0)) type = "local memory allocation";
115 XtErrorMsg("allocError", type, XtCXtToolkitError,
116 "Cannot perform %s", &type, &num_params);
117}
118
119void _XtHeapInit(
120 Heap* heap)
121{
122 heap->start = NULL((void*)0);
123 heap->bytes_remaining = 0;
124}
125
126/* Version of asprintf() using XtMalloc
127 * Not currently available in XTTRACEMEMORY version, since that would
128 * require varargs macros everywhere, which are only standard in C99 & later.
129 */
130Cardinal XtAsprintf(
131 String *new_string,
132 _Xconstconst char * _X_RESTRICT_KYWDrestrict format,
133 ...)
134{
135 char buf[256];
136 int len;
137 va_list ap;
138
139 va_start(ap, format)__builtin_va_start(ap, format);
140 len = vsnprintf(buf, sizeof(buf), format, ap)__builtin___vsnprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), format, ap)
;
141 va_end(ap)__builtin_va_end(ap);
142
143 if (len < 0)
1
Assuming 'len' is >= 0
2
Taking false branch
144 _XtAllocError("vsnprintf");
145
146 *new_string = XtMalloc(len + 1); /* snprintf doesn't count trailing '\0' */
147 if (len < sizeof(buf))
3
Taking true branch
148 {
149 strncpy(*new_string, buf, len)__builtin___strncpy_chk (*new_string, buf, len, __builtin_object_size
(*new_string, 2 > 1 ? 1 : 0))
;
4
Within the expansion of the macro 'strncpy':
a
Null pointer argument in call to string copy function
150 (*new_string)[len] = '\0';
151 }
152 else
153 {
154 va_start(ap, format)__builtin_va_start(ap, format);
155 if (vsnprintf(*new_string, len + 1, format, ap)__builtin___vsnprintf_chk (*new_string, len + 1, 0, __builtin_object_size
(*new_string, 2 > 1 ? 1 : 0), format, ap)
< 0)
156 _XtAllocError("vsnprintf");
157 va_end(ap)__builtin_va_end(ap);
158 }
159 return len;
160}
161
162
163#ifndef XTTRACEMEMORY
164
165char *XtMalloc(
166 unsigned size)
167{
168 char *ptr;
169
170#if defined(MALLOC_0_RETURNS_NULL) && defined(XTMALLOC_BC)
171 /* preserve this (broken) behavior until everyone fixes their apps */
172 if (!size) size = 1;
173#endif
174 if ((ptr = Xmalloc(size)malloc((size))) == NULL((void*)0))
175 _XtAllocError("malloc");
176
177 return(ptr);
178}
179
180char *XtRealloc(
181 char *ptr,
182 unsigned size)
183{
184 if (ptr == NULL((void*)0)) {
185#ifdef MALLOC_0_RETURNS_NULL
186 if (!size) size = 1;
187#endif
188 return(XtMalloc(size));
189 } else if ((ptr = Xrealloc(ptr, size)realloc((ptr), (size))) == NULL((void*)0)
190#ifdef MALLOC_0_RETURNS_NULL
191 && size
192#endif
193 )
194 _XtAllocError("realloc");
195
196 return(ptr);
197}
198
199char *XtCalloc(
200 unsigned num, unsigned size)
201{
202 char *ptr;
203
204#if defined(MALLOC_0_RETURNS_NULL) && defined(XTMALLOC_BC)
205 /* preserve this (broken) behavior until everyone fixes their apps */
206 if (!size) num = size = 1;
207#endif
208 if ((ptr = Xcalloc(num, size)calloc((num), (size))) == NULL((void*)0))
209 _XtAllocError("calloc");
210
211 return(ptr);
212}
213
214void XtFree(
215 char *ptr)
216{
217 if (ptr != NULL((void*)0)) Xfree(ptr)free(ptr);
218}
219
220char* __XtMalloc(
221 unsigned size)
222{
223#ifdef MALLOC_0_RETURNS_NULL
224 if (!size) size = 1;
225#endif
226 return XtMalloc (size);
227}
228
229char* __XtCalloc(
230 unsigned num, unsigned size)
231{
232#ifdef MALLOC_0_RETURNS_NULL
233 if (!size) num = size = 1;
234#endif
235 return XtCalloc(num, size);
236}
237
238#ifndef HEAP_SEGMENT_SIZE1492
239#define HEAP_SEGMENT_SIZE1492 1492
240#endif
241
242char* _XtHeapAlloc(
243 Heap* heap,
244 Cardinal bytes)
245{
246 register char* heap_loc;
247 if (heap == NULL((void*)0)) return XtMalloc(bytes);
248 if (heap->bytes_remaining < (int)bytes) {
249 if ((bytes + sizeof(char*)) >= (HEAP_SEGMENT_SIZE1492>>1)) {
250 /* preserve current segment; insert this one in front */
251#ifdef _TRACE_HEAP
252 printf( "allocating large segment (%d bytes) on heap %#x\n",
253 bytes, heap );
254#endif
255 heap_loc = XtMalloc(bytes + sizeof(char*));
256 if (heap->start) {
257 *(char**)heap_loc = *(char**)heap->start;
258 *(char**)heap->start = heap_loc;
259 }
260 else {
261 *(char**)heap_loc = NULL((void*)0);
262 heap->start = heap_loc;
263 }
264 return heap_loc + sizeof(char*);
265 }
266 /* else discard remainder of this segment */
267#ifdef _TRACE_HEAP
268 printf( "allocating new segment on heap %#x\n", heap );
269#endif
270 heap_loc = XtMalloc((unsigned)HEAP_SEGMENT_SIZE1492);
271 *(char**)heap_loc = heap->start;
272 heap->start = heap_loc;
273 heap->current = heap_loc + sizeof(char*);
274 heap->bytes_remaining = HEAP_SEGMENT_SIZE1492 - sizeof(char*);
275 }
276 bytes = (bytes + (sizeof(long) - 1)) & (~(sizeof(long) - 1));
277 heap_loc = heap->current;
278 heap->current += bytes;
279 heap->bytes_remaining -= bytes; /* can be negative, if rounded */
280 return heap_loc;
281}
282
283void _XtHeapFree(
284 Heap* heap)
285{
286 char* segment = heap->start;
287 while (segment != NULL((void*)0)) {
288 char* next_segment = *(char**)segment;
289 XtFree(segment);
290 segment = next_segment;
291 }
292 heap->start = NULL((void*)0);
293 heap->bytes_remaining = 0;
294}
295
296#else
297
298/*
299 * X Toolkit Memory Trace Allocation Routines
300 */
301
302#undef XtMalloc
303#undef XtRealloc
304#undef XtCalloc
305#undef XtFree
306
307typedef struct _Stats *StatsPtr;
308typedef struct _Stats {
309 StatsPtr prev, next;
310 char *file;
311 int line;
312 unsigned size;
313 unsigned long seq;
314 XtPointer heap;
315} Stats;
316
317static StatsPtr XtMemory = (StatsPtr)NULL((void*)0);
318static unsigned long ActiveXtMemory = 0;
319static unsigned long XtSeqId = 0;
320static unsigned long XtSeqBreakpoint = ~0;
321
322#define StatsSize(n) ((((n) + (sizeof(long) - 1)) & ~(sizeof(long) - 1)) + sizeof(Stats))
323#define ToStats(ptr) ((StatsPtr)(ptr - sizeof(Stats)))
324#define ToMem(ptr) (((char *)ptr) + sizeof(Stats))
325
326#define CHAIN(ptr,len,hp) \
327 ptr->next = XtMemory; \
328 if (XtMemory) \
329 XtMemory->prev = ptr; \
330 XtMemory = ptr; \
331 ptr->prev = (StatsPtr)NULL((void*)0); \
332 ptr->file = file; \
333 ptr->line = line; \
334 ptr->size = len; \
335 ptr->heap = hp; \
336 if (file) \
337 ActiveXtMemory += len; \
338 ptr->seq = XtSeqId; \
339 if (XtSeqId == XtSeqBreakpoint) \
340 _XtBreakpoint(ptr); \
341 XtSeqId++
342
343/*ARGUSED*/
344static void _XtBreakpoint(
345 StatsPtr mem)
346{
347 mem->seq = XtSeqId; /* avoid being optimized out of existence */
348}
349
350char *_XtMalloc(
351 unsigned size,
352 char *file,
353 int line)
354{
355 StatsPtr ptr;
356 unsigned newsize;
357 char* retval = NULL((void*)0);
358
359 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
360 newsize = StatsSize(size);
361 if ((ptr = (StatsPtr)Xmalloc(newsize)malloc((newsize))) == NULL((void*)0))
362 _XtAllocError("malloc");
363 CHAIN(ptr, size, NULL((void*)0));
364 retval = (ToMem(ptr));
365 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
366 return retval;
367}
368
369char *XtMalloc(
370 unsigned size)
371{
372 return _XtMalloc(size, (char *)NULL((void*)0), 0);
373}
374
375char *_XtRealloc(
376 char *ptr,
377 unsigned size,
378 char *file,
379 int line)
380{
381 char *newptr;
382
383 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
384 newptr = _XtMalloc(size, file, line);
385 if (ptr) {
386 unsigned copysize = ToStats(ptr)->size;
387 if (copysize > size) copysize = size;
388 memmove(newptr, ptr, copysize)__builtin___memmove_chk (newptr, ptr, copysize, __builtin_object_size
(newptr, 0))
;
389 _XtFree(ptr);
390 }
391 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
392 return(newptr);
393}
394
395char *XtRealloc(
396 char *ptr,
397 unsigned size)
398{
399 return _XtRealloc(ptr, size, (char *)NULL((void*)0), 0);
400}
401
402char *_XtCalloc(
403 unsigned num, unsigned size,
404 char *file,
405 int line)
406{
407 StatsPtr ptr;
408 unsigned total, newsize;
409 char* retval = NULL((void*)0);
410
411 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
412 total = num * size;
413 newsize = StatsSize(total);
414 if ((ptr = (StatsPtr)Xcalloc(newsize, 1)calloc((newsize), (1))) == NULL((void*)0))
415 _XtAllocError("calloc");
416 CHAIN(ptr, total, NULL((void*)0));
417 retval = (ToMem(ptr));
418 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
419 return retval;
420}
421
422char *XtCalloc(
423 unsigned num, unsigned size)
424{
425 return _XtCalloc(num, size, (char *)NULL((void*)0), 0);
426}
427
428Boolean _XtIsValidPointer(
429 char *ptr)
430{
431 register StatsPtr mem;
432 register StatsPtr stp = ToStats(ptr);
433
434 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
435 for (mem = XtMemory; mem; mem = mem->next) {
436 if (mem == stp) {
437 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
438 return True1;
439 }
440 }
441 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
442 return False0;
443}
444
445Boolean _XtValidateMemory = False0;
446
447void _XtFree(
448 char *ptr)
449{
450 register StatsPtr stp;
451
452 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
453 if (ptr) {
454 if (_XtValidateMemory && !_XtIsValidPointer(ptr))
455 abort();
456 stp = ToStats(ptr);
457 if (stp->file)
458 ActiveXtMemory -= stp->size;
459 if (stp->prev)
460 stp->prev->next = stp->next;
461 else
462 XtMemory = stp->next;
463 if (stp->next)
464 stp->next->prev = stp->prev;
465 Xfree((char *)stp)free((char *)stp);
466 }
467 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
468}
469
470void XtFree(char *ptr)
471{
472 _XtFree(ptr);
473}
474
475char *_XtHeapMalloc(
476 Heap *heap,
477 Cardinal size,
478 char *file,
479 int line)
480{
481 StatsPtr ptr;
482 unsigned newsize;
483 XtPointer hp = (XtPointer) heap;
484 char* retval = NULL((void*)0);
485
486 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
487 newsize = StatsSize(size);
488 if ((ptr = (StatsPtr)Xmalloc(newsize)malloc((newsize))) == NULL((void*)0))
489 _XtAllocError("malloc");
490 CHAIN(ptr, size, hp);
491 retval = (ToMem(ptr));
492 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
493 return retval;
494}
495
496void _XtHeapFree(register XtPointer heap)
497{
498 register StatsPtr mem, next;
499
500 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
501 for (mem = XtMemory; mem; mem = next) {
502 next = mem->next;
503 if (mem->heap == heap) {
504 if (mem->file)
505 ActiveXtMemory -= mem->size;
506 if (mem->prev)
507 mem->prev->next = next;
508 else
509 XtMemory = next;
510 if (next)
511 next->prev = mem->prev;
512 Xfree((char *)mem)free((char *)mem);
513 }
514 }
515 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
516}
517
518#include <stdio.h>
519
520void _XtPrintMemory(char * filename)
521{
522 register StatsPtr mem;
523 FILE *f;
524
525 if (filename == NULL((void*)0))
526 f = stderr__stderrp;
527 else
528 f = fopen(filename, "w");
529 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
530 fprintf(f, "total size: %d\n", ActiveXtMemory);
531 for (mem = XtMemory; mem; mem = mem->next) {
532 if (mem->file)
533 fprintf(f, "size: %6d seq: %5d %12s(%4d) %s\n",
534 mem->size, mem->seq,
535 mem->file, mem->line, mem->heap ? "heap" : "");
536 }
537 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
538 if (filename) fclose(f);
539}
540
541#endif /* XTTRACEMEMORY */