Bug Summary

File:parse.c
Location:line 387, column 30
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/*
2 * Copyright (C) 1989-95 GROUPE BULL
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
24 */
25
26/*****************************************************************************\
27* parse.c: *
28* *
29* XPM library *
30* Parse an XPM file or array and store the found informations *
31* in the given XpmImage structure. *
32* *
33* Developed by Arnaud Le Hors *
34\*****************************************************************************/
35
36/*
37 * The code related to FOR_MSW has been added by
38 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
39 */
40
41/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
42
43#ifdef HAVE_CONFIG_H1
44#include <config.h>
45#endif
46#include "XpmI.h"
47#include <ctype.h>
48#include <string.h>
49
50#if defined(HAS_STRLCAT) || defined(HAVE_STRLCAT)
51# define STRLCAT(dst, src, dstsize)do { if ((strlen(dst) + strlen(src)) < (dstsize)) strcat(dst
, src); else return (-2); } while(0)
do { \
52 if (strlcat(dst, src, dstsize) >= (dstsize)) \
53 return (XpmFileInvalid-2); } while(0)
54# define STRLCPY(dst, src, dstsize)do { if (strlen(src) < (dstsize)) strcpy(dst, src); else return
(-2); } while(0)
do { \
55 if (strlcpy(dst, src, dstsize) >= (dstsize)) \
56 return (XpmFileInvalid-2); } while(0)
57#else
58# define STRLCAT(dst, src, dstsize)do { if ((strlen(dst) + strlen(src)) < (dstsize)) strcat(dst
, src); else return (-2); } while(0)
do { \
59 if ((strlen(dst) + strlen(src)) < (dstsize)) \
60 strcat(dst, src); \
61 else return (XpmFileInvalid-2); } while(0)
62# define STRLCPY(dst, src, dstsize)do { if (strlen(src) < (dstsize)) strcpy(dst, src); else return
(-2); } while(0)
do { \
63 if (strlen(src) < (dstsize)) \
64 strcpy(dst, src); \
65 else return (XpmFileInvalid-2); } while(0)
66#endif
67
68LFUNC(ParsePixels, int, (xpmData *data, unsigned int width,static int ParsePixels (xpmData *data, unsigned int width, unsigned
int height, unsigned int ncolors, unsigned int cpp, XpmColor
*colorTable, xpmHashTable *hashtable, unsigned int **pixels)
69 unsigned int height, unsigned int ncolors,static int ParsePixels (xpmData *data, unsigned int width, unsigned
int height, unsigned int ncolors, unsigned int cpp, XpmColor
*colorTable, xpmHashTable *hashtable, unsigned int **pixels)
70 unsigned int cpp, XpmColor *colorTable,static int ParsePixels (xpmData *data, unsigned int width, unsigned
int height, unsigned int ncolors, unsigned int cpp, XpmColor
*colorTable, xpmHashTable *hashtable, unsigned int **pixels)
71 xpmHashTable *hashtable, unsigned int **pixels))static int ParsePixels (xpmData *data, unsigned int width, unsigned
int height, unsigned int ncolors, unsigned int cpp, XpmColor
*colorTable, xpmHashTable *hashtable, unsigned int **pixels)
;
72
73const char *xpmColorKeys[] = {
74 "s", /* key #1: symbol */
75 "m", /* key #2: mono visual */
76 "g4", /* key #3: 4 grays visual */
77 "g", /* key #4: gray visual */
78 "c", /* key #5: color visual */
79};
80
81int
82xpmParseValues(
83 xpmData *data,
84 unsigned int *width,
85 unsigned int *height,
86 unsigned int *ncolors,
87 unsigned int *cpp,
88 unsigned int *x_hotspot,
89 unsigned int *y_hotspot,
90 unsigned int *hotspot,
91 unsigned int *extensions)
92{
93 unsigned int l;
94 char buf[BUFSIZ8192 + 1];
95
96 if (!data->format) { /* XPM 2 or 3 */
97
98 /*
99 * read values: width, height, ncolors, chars_per_pixel
100 */
101 if (!(xpmNextUI(data, width) && xpmNextUI(data, height)
102 && xpmNextUI(data, ncolors) && xpmNextUI(data, cpp)))
103 return (XpmFileInvalid-2);
104
105 /*
106 * read optional information (hotspot and/or XPMEXT) if any
107 */
108 l = xpmNextWord(data, buf, BUFSIZ8192);
109 if (l) {
110 *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
111 if (*extensions)
112 *hotspot = (xpmNextUI(data, x_hotspot)
113 && xpmNextUI(data, y_hotspot));
114 else {
115 *hotspot = (xpmatoui(buf, l, x_hotspot)
116 && xpmNextUI(data, y_hotspot));
117 l = xpmNextWord(data, buf, BUFSIZ8192);
118 *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
119 }
120 }
121 } else {
122
123 /*
124 * XPM 1 file read values: width, height, ncolors, chars_per_pixel
125 */
126 int i;
127 char *ptr;
128 Boolint got_one, saw_width = False0, saw_height = False0;
129 Boolint saw_ncolors = False0, saw_chars_per_pixel = False0;
130
131 for (i = 0; i < 4; i++) {
132 l = xpmNextWord(data, buf, BUFSIZ8192);
133 if (l != 7 || strncmp("#define", buf, 7))
134 return (XpmFileInvalid-2);
135 l = xpmNextWord(data, buf, BUFSIZ8192);
136 if (!l)
137 return (XpmFileInvalid-2);
138 buf[l] = '\0';
139 ptr = buf;
140 got_one = False0;
141 while (!got_one) {
142 ptr = strchr(ptr, '_');
143 if (!ptr)
144 return (XpmFileInvalid-2);
145 switch (l - (ptr - buf)) {
146 case 6:
147 if (saw_width || strncmp("_width", ptr, 6)
148 || !xpmNextUI(data, width))
149 return (XpmFileInvalid-2);
150 else
151 saw_width = True1;
152 got_one = True1;
153 break;
154 case 7:
155 if (saw_height || strncmp("_height", ptr, 7)
156 || !xpmNextUI(data, height))
157 return (XpmFileInvalid-2);
158 else
159 saw_height = True1;
160 got_one = True1;
161 break;
162 case 8:
163 if (saw_ncolors || strncmp("_ncolors", ptr, 8)
164 || !xpmNextUI(data, ncolors))
165 return (XpmFileInvalid-2);
166 else
167 saw_ncolors = True1;
168 got_one = True1;
169 break;
170 case 16:
171 if (saw_chars_per_pixel
172 || strncmp("_chars_per_pixel", ptr, 16)
173 || !xpmNextUI(data, cpp))
174 return (XpmFileInvalid-2);
175 else
176 saw_chars_per_pixel = True1;
177 got_one = True1;
178 break;
179 default:
180 ptr++;
181 }
182 }
183 /* skip the end of line */
184 xpmNextString(data);
185 }
186 if (!saw_width || !saw_height || !saw_ncolors || !saw_chars_per_pixel)
187 return (XpmFileInvalid-2);
188
189 *hotspot = 0;
190 *extensions = 0;
191 }
192 return (XpmSuccess0);
193}
194
195int
196xpmParseColors(
197 xpmData *data,
198 unsigned int ncolors,
199 unsigned int cpp,
200 XpmColor **colorTablePtr,
201 xpmHashTable *hashtable)
202{
203 unsigned int key = 0, l, a, b, len;
204 unsigned int curkey; /* current color key */
205 unsigned int lastwaskey; /* key read */
206 char buf[BUFSIZ8192+1];
207 char curbuf[BUFSIZ8192]; /* current buffer */
208 const char **sptr;
209 char *s;
210 XpmColor *color;
211 XpmColor *colorTable;
212 char **defaults;
213 int ErrorStatus;
214
215 if (ncolors >= UINT_MAX(2147483647 *2U +1U) / sizeof(XpmColor))
216 return (XpmNoMemory-3);
217 colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor))calloc((ncolors), (sizeof(XpmColor)));
218 if (!colorTable)
219 return (XpmNoMemory-3);
220
221 if (!data->format) { /* XPM 2 or 3 */
222 for (a = 0, color = colorTable; a < ncolors; a++, color++) {
223 xpmNextString(data); /* skip the line */
224
225 /*
226 * read pixel value
227 */
228 if (cpp >= UINT_MAX(2147483647 *2U +1U) - 1) {
229 xpmFreeColorTable(colorTable, ncolors);
230 return (XpmNoMemory-3);
231 }
232 color->string = (char *) XpmMalloc(cpp + 1)malloc((cpp + 1));
233 if (!color->string) {
234 xpmFreeColorTable(colorTable, ncolors);
235 return (XpmNoMemory-3);
236 }
237 for (b = 0, s = color->string; b < cpp; b++, s++)
238 *s = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
239 *s = '\0';
240
241 /*
242 * store the string in the hashtable with its color index number
243 */
244 if (USE_HASHTABLE(cpp > 2 && ncolors > 4)) {
245 ErrorStatus =
246 xpmHashIntern(hashtable, color->string, HashAtomData(a)((void *)(long)a));
247 if (ErrorStatus != XpmSuccess0) {
248 xpmFreeColorTable(colorTable, ncolors);
249 return (ErrorStatus);
250 }
251 }
252
253 /*
254 * read color keys and values
255 */
256 defaults = (char **) color;
257 curkey = 0;
258 lastwaskey = 0;
259 *curbuf = '\0'; /* init curbuf */
260 while ((l = xpmNextWord(data, buf, BUFSIZ8192))) {
261 if (!lastwaskey) {
262 for (key = 0, sptr = xpmColorKeys; key < NKEYS5; key++,
263 sptr++)
264 if ((strlen(*sptr) == l) && (!strncmp(*sptr, buf, l)))
265 break;
266 }
267 if (!lastwaskey && key < NKEYS5) { /* open new key */
268 if (curkey) { /* flush string */
269 len = strlen(curbuf) + 1;
270 s = (char *) XpmMalloc(len)malloc((len));
271 if (!s) {
272 xpmFreeColorTable(colorTable, ncolors);
273 return (XpmNoMemory-3);
274 }
275 defaults[curkey] = s;
276 memcpy(s, curbuf, len);
277 }
278 curkey = key + 1; /* set new key */
279 *curbuf = '\0'; /* reset curbuf */
280 lastwaskey = 1;
281 } else {
282 if (!curkey) { /* key without value */
283 xpmFreeColorTable(colorTable, ncolors);
284 return (XpmFileInvalid-2);
285 }
286 if (!lastwaskey)
287 STRLCAT(curbuf, " ", sizeof(curbuf))do { if ((strlen(curbuf) + strlen(" ")) < (sizeof(curbuf))
) strcat(curbuf, " "); else return (-2); } while(0)
;/* append space */
288 buf[l] = '\0';
289 STRLCAT(curbuf, buf, sizeof(curbuf))do { if ((strlen(curbuf) + strlen(buf)) < (sizeof(curbuf))
) strcat(curbuf, buf); else return (-2); } while(0)
; /* append buf */
290 lastwaskey = 0;
291 }
292 }
293 if (!curkey) { /* key without value */
294 xpmFreeColorTable(colorTable, ncolors);
295 return (XpmFileInvalid-2);
296 }
297 len = strlen(curbuf) + 1; /* integer overflow just theoretically possible */
298 s = defaults[curkey] = (char *) XpmMalloc(len)malloc((len));
299 if (!s) {
300 xpmFreeColorTable(colorTable, ncolors);
301 return (XpmNoMemory-3);
302 }
303 memcpy(s, curbuf, len);
304 }
305 } else { /* XPM 1 */
306 /* get to the beginning of the first string */
307 data->Bos = '"';
308 data->Eos = '\0';
309 xpmNextString(data);
310 data->Eos = '"';
311 for (a = 0, color = colorTable; a < ncolors; a++, color++) {
312
313 /*
314 * read pixel value
315 */
316 if (cpp >= UINT_MAX(2147483647 *2U +1U) - 1) {
317 xpmFreeColorTable(colorTable, ncolors);
318 return (XpmNoMemory-3);
319 }
320 color->string = (char *) XpmMalloc(cpp + 1)malloc((cpp + 1));
321 if (!color->string) {
322 xpmFreeColorTable(colorTable, ncolors);
323 return (XpmNoMemory-3);
324 }
325 for (b = 0, s = color->string; b < cpp; b++, s++)
326 *s = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
327 *s = '\0';
328
329 /*
330 * store the string in the hashtable with its color index number
331 */
332 if (USE_HASHTABLE(cpp > 2 && ncolors > 4)) {
333 ErrorStatus =
334 xpmHashIntern(hashtable, color->string, HashAtomData(a)((void *)(long)a));
335 if (ErrorStatus != XpmSuccess0) {
336 xpmFreeColorTable(colorTable, ncolors);
337 return (ErrorStatus);
338 }
339 }
340
341 /*
342 * read color values
343 */
344 xpmNextString(data); /* get to the next string */
345 *curbuf = '\0'; /* init curbuf */
346 while ((l = xpmNextWord(data, buf, BUFSIZ8192))) {
347 if (*curbuf != '\0')
348 STRLCAT(curbuf, " ", sizeof(curbuf))do { if ((strlen(curbuf) + strlen(" ")) < (sizeof(curbuf))
) strcat(curbuf, " "); else return (-2); } while(0)
;/* append space */
349 buf[l] = '\0';
350 STRLCAT(curbuf, buf, sizeof(curbuf))do { if ((strlen(curbuf) + strlen(buf)) < (sizeof(curbuf))
) strcat(curbuf, buf); else return (-2); } while(0)
; /* append buf */
351 }
352 len = strlen(curbuf) + 1;
353 s = (char *) XpmMalloc(len)malloc((len));
354 if (!s) {
355 xpmFreeColorTable(colorTable, ncolors);
356 return (XpmNoMemory-3);
357 }
358 memcpy(s, curbuf, len);
359 color->c_color = s;
360 *curbuf = '\0'; /* reset curbuf */
361 if (a < ncolors - 1) /* can we trust ncolors -> leave data's bounds */
362 xpmNextString(data); /* get to the next string */
363 }
364 }
365 *colorTablePtr = colorTable;
366 return (XpmSuccess0);
367}
368
369static int
370ParsePixels(
371 xpmData *data,
372 unsigned int width,
373 unsigned int height,
374 unsigned int ncolors,
375 unsigned int cpp,
376 XpmColor *colorTable,
377 xpmHashTable *hashtable,
378 unsigned int **pixels)
379{
380 unsigned int *iptr, *iptr2 = NULL((void*)0); /* found by Egbert Eich */
381 unsigned int a, x, y;
382
383 if ((height > 0 && width >= UINT_MAX(2147483647 *2U +1U) / height) ||
1
Assuming 'height' is <= 0
2
Taking false branch
384 width * height >= UINT_MAX(2147483647 *2U +1U) / sizeof(unsigned int))
385 return XpmNoMemory-3;
386#ifndef FOR_MSW
387 iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height)malloc((sizeof(unsigned int) * width * height));
3
Within the expansion of the macro 'XpmMalloc':
a
Call to 'malloc' has an allocation size of 0 bytes
388#else
389
390 /*
391 * special treatment to trick DOS malloc(size_t) where size_t is 16 bit!!
392 * XpmMalloc is defined to longMalloc(long) and checks the 16 bit boundary
393 */
394 iptr2 = (unsigned int *)
395 XpmMalloc((long) sizeof(unsigned int) * (long) width * (long) height)malloc(((long) sizeof(unsigned int) * (long) width * (long) height
))
;
396#endif
397 if (!iptr2)
398 return (XpmNoMemory-3);
399
400 iptr = iptr2;
401
402 switch (cpp) {
403
404 case (1): /* Optimize for single character
405 * colors */
406 {
407 unsigned short colidx[256];
408
409 if (ncolors > 256) {
410 XpmFree(iptr2)free(iptr2); /* found by Egbert Eich */
411 return (XpmFileInvalid-2);
412 }
413
414 bzero((char *)colidx, 256 * sizeof(short))memset((char *)colidx,0,256 * sizeof(short));
415 for (a = 0; a < ncolors; a++)
416 colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
417
418 for (y = 0; y < height; y++) {
419 xpmNextString(data);
420 for (x = 0; x < width; x++, iptr++) {
421 int c = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
422
423 if (c > 0 && c < 256 && colidx[c] != 0)
424 *iptr = colidx[c] - 1;
425 else {
426 XpmFree(iptr2)free(iptr2);
427 return (XpmFileInvalid-2);
428 }
429 }
430 }
431 }
432 break;
433
434 case (2): /* Optimize for double character
435 * colors */
436 {
437
438/* free all allocated pointers at all exits */
439#define FREE_CIDXdo { int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx
[f]); } while(0)
\
440do \
441{ \
442 int f; for (f = 0; f < 256; f++) \
443 if (cidx[f]) XpmFree(cidx[f])free(cidx[f]); \
444} while(0)
445
446 /* array of pointers malloced by need */
447 unsigned short *cidx[256];
448 unsigned int char1;
449
450 bzero((char *)cidx, 256 * sizeof(unsigned short *))memset((char *)cidx,0,256 * sizeof(unsigned short *)); /* init */
451 for (a = 0; a < ncolors; a++) {
452 char1 = (unsigned char) colorTable[a].string[0];
453 if (cidx[char1] == NULL((void*)0)) { /* get new memory */
454 cidx[char1] = (unsigned short *)
455 XpmCalloc(256, sizeof(unsigned short))calloc((256), (sizeof(unsigned short)));
456 if (cidx[char1] == NULL((void*)0)) { /* new block failed */
457 FREE_CIDXdo { int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx
[f]); } while(0)
;
458 XpmFree(iptr2)free(iptr2);
459 return (XpmNoMemory-3);
460 }
461 }
462 cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
463 }
464
465 for (y = 0; y < height; y++) {
466 xpmNextString(data);
467 for (x = 0; x < width; x++, iptr++) {
468 int cc1 = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
469 if (cc1 > 0 && cc1 < 256) {
470 int cc2 = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
471 if (cc2 > 0 && cc2 < 256 &&
472 cidx[cc1] && cidx[cc1][cc2] != 0)
473 *iptr = cidx[cc1][cc2] - 1;
474 else {
475 FREE_CIDXdo { int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx
[f]); } while(0)
;
476 XpmFree(iptr2)free(iptr2);
477 return (XpmFileInvalid-2);
478 }
479 } else {
480 FREE_CIDXdo { int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx
[f]); } while(0)
;
481 XpmFree(iptr2)free(iptr2);
482 return (XpmFileInvalid-2);
483 }
484 }
485 }
486 FREE_CIDXdo { int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx
[f]); } while(0)
;
487 }
488 break;
489
490 default: /* Non-optimized case of long color
491 * names */
492 {
493 char *s;
494 char buf[BUFSIZ8192];
495
496 if (cpp >= sizeof(buf)) {
497 XpmFree(iptr2)free(iptr2); /* found by Egbert Eich */
498 return (XpmFileInvalid-2);
499 }
500
501 buf[cpp] = '\0';
502 if (USE_HASHTABLE(cpp > 2 && ncolors > 4)) {
503 xpmHashAtom *slot;
504
505 for (y = 0; y < height; y++) {
506 xpmNextString(data);
507 for (x = 0; x < width; x++, iptr++) {
508 for (a = 0, s = buf; a < cpp; a++, s++)
509 *s = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
; /* int assigned to char, not a problem here */
510 slot = xpmHashSlot(hashtable, buf);
511 if (!*slot) { /* no color matches */
512 XpmFree(iptr2)free(iptr2);
513 return (XpmFileInvalid-2);
514 }
515 *iptr = HashColorIndex(slot)((unsigned long)((*slot)->data));
516 }
517 }
518 } else {
519 for (y = 0; y < height; y++) {
520 xpmNextString(data);
521 for (x = 0; x < width; x++, iptr++) {
522 for (a = 0, s = buf; a < cpp; a++, s++)
523 *s = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
; /* int assigned to char, not a problem here */
524 for (a = 0; a < ncolors; a++)
525 if (!strcmp(colorTable[a].string, buf))
526 break;
527 if (a == ncolors) { /* no color matches */
528 XpmFree(iptr2)free(iptr2);
529 return (XpmFileInvalid-2);
530 }
531 *iptr = a;
532 }
533 }
534 }
535 }
536 break;
537 }
538 *pixels = iptr2;
539 return (XpmSuccess0);
540}
541
542int
543xpmParseExtensions(
544 xpmData *data,
545 XpmExtension **extensions,
546 unsigned int *nextensions)
547{
548 XpmExtension *exts = NULL((void*)0), *ext;
549 unsigned int num = 0;
550 unsigned int nlines, a, l, notstart, notend = 0;
551 int status;
552 char *string, *s, *s2, **sp;
553
554 xpmNextString(data);
555 exts = (XpmExtension *) XpmMalloc(sizeof(XpmExtension))malloc((sizeof(XpmExtension)));
556 /* get the whole string */
557 status = xpmGetString(data, &string, &l);
558 if (status != XpmSuccess0) {
559 XpmFree(exts)free(exts);
560 return (status);
561 }
562 /* look for the key word XPMEXT, skip lines before this */
563 while ((notstart = strncmp("XPMEXT", string, 6))
564 && (notend = strncmp("XPMENDEXT", string, 9))) {
565 XpmFree(string)free(string);
566 xpmNextString(data);
567 status = xpmGetString(data, &string, &l);
568 if (status != XpmSuccess0) {
569 XpmFree(exts)free(exts);
570 return (status);
571 }
572 }
573 if (!notstart)
574 notend = strncmp("XPMENDEXT", string, 9);
575 while (!notstart && notend) {
576 /* there starts an extension */
577 ext = (XpmExtension *)
578 XpmRealloc(exts, (num + 1) * sizeof(XpmExtension))realloc((exts), ((num + 1) * sizeof(XpmExtension))); /* can the loop be forced to iterate often enough to make "(num + 1) * sizeof(XpmExtension)" wrapping? */
579 if (!ext) {
580 XpmFree(string)free(string);
581 XpmFreeExtensions(exts, num);
582 return (XpmNoMemory-3);
583 }
584 exts = ext;
585 ext += num;
586 /* skip whitespace and store its name */
587 s2 = s = string + 6;
588 while (isspace(*s2)((*__ctype_b_loc ())[(int) ((*s2))] & (unsigned short int
) _ISspace)
)
589 s2++;
590 a = s2 - s;
591 ext->name = (char *) XpmMalloc(l - a - 6)malloc((l - a - 6));
592 if (!ext->name) {
593 XpmFree(string)free(string);
594 ext->lines = NULL((void*)0);
595 ext->nlines = 0;
596 XpmFreeExtensions(exts, num + 1);
597 return (XpmNoMemory-3);
598 }
599 strncpy(ext->name, s + a, l - a - 6);
600 XpmFree(string)free(string);
601 /* now store the related lines */
602 xpmNextString(data);
603 status = xpmGetString(data, &string, &l);
604 if (status != XpmSuccess0) {
605 ext->lines = NULL((void*)0);
606 ext->nlines = 0;
607 XpmFreeExtensions(exts, num + 1);
608 return (status);
609 }
610 ext->lines = (char **) XpmMalloc(sizeof(char *))malloc((sizeof(char *)));
611 nlines = 0;
612 while ((notstart = strncmp("XPMEXT", string, 6))
613 && (notend = strncmp("XPMENDEXT", string, 9))) {
614 sp = (char **)
615 XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *))realloc((ext->lines), ((nlines + 1) * sizeof(char *))); /* can we iterate enough for a wrapping? */
616 if (!sp) {
617 XpmFree(string)free(string);
618 ext->nlines = nlines;
619 XpmFreeExtensions(exts, num + 1);
620 return (XpmNoMemory-3);
621 }
622 ext->lines = sp;
623 ext->lines[nlines] = string;
624 nlines++;
625 xpmNextString(data);
626 status = xpmGetString(data, &string, &l);
627 if (status != XpmSuccess0) {
628 ext->nlines = nlines;
629 XpmFreeExtensions(exts, num + 1);
630 return (status);
631 }
632 }
633 if (!nlines) {
634 XpmFree(ext->lines)free(ext->lines);
635 ext->lines = NULL((void*)0);
636 }
637 ext->nlines = nlines;
638 num++;
639 }
640 if (!num) {
641 XpmFree(string)free(string);
642 XpmFree(exts)free(exts);
643 exts = NULL((void*)0);
644 } else if (!notend)
645 XpmFree(string)free(string);
646 *nextensions = num;
647 *extensions = exts;
648 return (XpmSuccess0);
649}
650
651
652/* function call in case of error */
653#undef RETURN
654#define RETURN(status)do { goto error; } while(0) \
655do { \
656 goto error; \
657} while(0)
658
659/*
660 * This function parses an Xpm file or data and store the found informations
661 * in an an XpmImage structure which is returned.
662 */
663int
664xpmParseData(
665 xpmData *data,
666 XpmImage *image,
667 XpmInfo *info)
668{
669 /* variables to return */
670 unsigned int width, height, ncolors, cpp;
671 unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
672 XpmColor *colorTable = NULL((void*)0);
673 unsigned int *pixelindex = NULL((void*)0);
674 char *hints_cmt = NULL((void*)0);
675 char *colors_cmt = NULL((void*)0);
676 char *pixels_cmt = NULL((void*)0);
677
678 unsigned int cmts;
679 int ErrorStatus;
680 xpmHashTable hashtable;
681
682 cmts = info && (info->valuemask & XpmReturnComments(1L<<8));
683
684 /*
685 * parse the header
686 */
687 ErrorStatus = xpmParseHeader(data);
688 if (ErrorStatus != XpmSuccess0)
689 return (ErrorStatus);
690
691 /*
692 * read values
693 */
694 ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
695 &x_hotspot, &y_hotspot, &hotspot,
696 &extensions);
697 if (ErrorStatus != XpmSuccess0)
698 return (ErrorStatus);
699
700 /*
701 * store the hints comment line
702 */
703 if (cmts)
704 xpmGetCmt(data, &hints_cmt);
705
706 /*
707 * init the hashtable
708 */
709 if (USE_HASHTABLE(cpp > 2 && ncolors > 4)) {
710 ErrorStatus = xpmHashTableInit(&hashtable);
711 if (ErrorStatus != XpmSuccess0)
712 RETURN(ErrorStatus)do { goto error; } while(0);
713 }
714
715 /*
716 * read colors
717 */
718 ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
719 if (ErrorStatus != XpmSuccess0) {
720 if (USE_HASHTABLE(cpp > 2 && ncolors > 4))
721 xpmHashTableFree(&hashtable);
722 RETURN(ErrorStatus)do { goto error; } while(0);
723 }
724
725 /*
726 * store the colors comment line
727 */
728 if (cmts)
729 xpmGetCmt(data, &colors_cmt);
730
731 /*
732 * read pixels and index them on color number
733 */
734 ErrorStatus = ParsePixels(data, width, height, ncolors, cpp, colorTable,
735 &hashtable, &pixelindex);
736
737 /*
738 * free the hastable
739 */
740 if (USE_HASHTABLE(cpp > 2 && ncolors > 4))
741 xpmHashTableFree(&hashtable);
742
743 if (ErrorStatus != XpmSuccess0)
744 RETURN(ErrorStatus)do { goto error; } while(0);
745
746 /*
747 * store the pixels comment line
748 */
749 if (cmts)
750 xpmGetCmt(data, &pixels_cmt);
751
752 /*
753 * parse extensions
754 */
755 if (info && (info->valuemask & XpmReturnExtensions(1L<<10))) {
756 if (extensions) {
757 ErrorStatus = xpmParseExtensions(data, &info->extensions,
758 &info->nextensions);
759 if (ErrorStatus != XpmSuccess0)
760 RETURN(ErrorStatus)do { goto error; } while(0);
761 } else {
762 info->extensions = NULL((void*)0);
763 info->nextensions = 0;
764 }
765 }
766
767 /*
768 * store found informations in the XpmImage structure
769 */
770 image->width = width;
771 image->height = height;
772 image->cpp = cpp;
773 image->ncolors = ncolors;
774 image->colorTable = colorTable;
775 image->data = pixelindex;
776
777 if (info) {
778 if (cmts) {
779 info->hints_cmt = hints_cmt;
780 info->colors_cmt = colors_cmt;
781 info->pixels_cmt = pixels_cmt;
782 }
783 if (hotspot) {
784 info->x_hotspot = x_hotspot;
785 info->y_hotspot = y_hotspot;
786 info->valuemask |= XpmHotspot(1L<<4);
787 }
788 }
789 return (XpmSuccess0);
790
791/* exit point in case of error, free only locally allocated variables */
792error:
793 if (colorTable)
794 xpmFreeColorTable(colorTable, ncolors);
795 if (pixelindex)
796 XpmFree(pixelindex)free(pixelindex);
797 if (hints_cmt)
798 XpmFree(hints_cmt)free(hints_cmt);
799 if (colors_cmt)
800 XpmFree(colors_cmt)free(colors_cmt);
801 if (pixels_cmt)
802 XpmFree(pixels_cmt)free(pixels_cmt);
803
804 return(ErrorStatus);
805}