|
|
* HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 | * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 |
*/ | */ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
#include <ctype.h> | #include <ctype.h> |
| |
|
|
*/ | */ |
} else { | } else { |
#endif | #endif |
int i; |
unsigned int i; |
| |
ncols = visual->map_entries; | ncols = visual->map_entries; |
cols = (XColor *) XpmCalloc(ncols, sizeof(XColor)); | cols = (XColor *) XpmCalloc(ncols, sizeof(XColor)); |
|
|
/* function call in case of error, frees only locally allocated variables */ | /* function call in case of error, frees only locally allocated variables */ |
#undef RETURN | #undef RETURN |
#define RETURN(status) \ | #define RETURN(status) \ |
|
do \ |
{ \ | { \ |
if (ximage) XDestroyImage(ximage); \ | if (ximage) XDestroyImage(ximage); \ |
if (shapeimage) XDestroyImage(shapeimage); \ | if (shapeimage) XDestroyImage(shapeimage); \ |
|
|
if (alloc_pixels) XpmFree(alloc_pixels); \ | if (alloc_pixels) XpmFree(alloc_pixels); \ |
if (used_pixels) XpmFree(used_pixels); \ | if (used_pixels) XpmFree(used_pixels); \ |
return (status); \ | return (status); \ |
} |
} while(0) |
| |
int | int |
XpmCreateImageFromXpmImage(display, image, | XpmCreateImageFromXpmImage(display, image, |
|
|
| |
ErrorStatus = XpmSuccess; | ErrorStatus = XpmSuccess; |
| |
if (image->ncolors >= SIZE_MAX / sizeof(Pixel)) |
if (image->ncolors >= UINT_MAX / sizeof(Pixel)) |
return (XpmNoMemory); | return (XpmNoMemory); |
| |
/* malloc pixels index tables */ | /* malloc pixels index tables */ |
|
|
return (XpmNoMemory); | return (XpmNoMemory); |
| |
#ifndef FOR_MSW | #ifndef FOR_MSW |
if (height != 0 && (*image_return)->bytes_per_line >= SIZE_MAX / height) |
if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) { |
|
XDestroyImage(*image_return); |
return XpmNoMemory; | return XpmNoMemory; |
|
} |
/* now that bytes_per_line must have been set properly alloc data */ | /* now that bytes_per_line must have been set properly alloc data */ |
|
if((*image_return)->bytes_per_line == 0 || height == 0) |
|
return XpmNoMemory; |
(*image_return)->data = | (*image_return)->data = |
(char *) XpmMalloc((*image_return)->bytes_per_line * height); | (char *) XpmMalloc((*image_return)->bytes_per_line * height); |
| |
|
|
LFUNC(_putbits, void, (register char *src, int dstoffset, | LFUNC(_putbits, void, (register char *src, int dstoffset, |
register int numbits, register char *dst)); | register int numbits, register char *dst)); |
| |
LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb)); |
LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb)); |
| |
static unsigned char Const _reverse_byte[0x100] = { | static unsigned char Const _reverse_byte[0x100] = { |
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, | 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, |
|
|
static int | static int |
_XReverse_Bytes(bpt, nb) | _XReverse_Bytes(bpt, nb) |
register unsigned char *bpt; | register unsigned char *bpt; |
register int nb; |
register unsigned int nb; |
{ | { |
do { | do { |
*bpt = _reverse_byte[*bpt]; | *bpt = _reverse_byte[*bpt]; |
bpt++; | bpt++; |
} while (--nb > 0); |
} while (--nb > 0); /* is nb user-controled? */ |
return 0; | return 0; |
} | } |
| |
|
|
register char *src; | register char *src; |
register char *dst; | register char *dst; |
register unsigned int *iptr; | register unsigned int *iptr; |
register int x, y, i; |
register unsigned int x, y, i; |
register char *data; | register char *data; |
Pixel pixel, px; | Pixel pixel, px; |
int nbytes, depth, ibu, ibpp; | int nbytes, depth, ibu, ibpp; |
|
|
depth = image->depth; | depth = image->depth; |
if (depth == 1) { | if (depth == 1) { |
ibu = image->bitmap_unit; | ibu = image->bitmap_unit; |
for (y = 0; y < height; y++) |
for (y = 0; y < height; y++) /* how can we trust height */ |
for (x = 0; x < width; x++, iptr++) { |
for (x = 0; x < width; x++, iptr++) { /* how can we trust width */ |
pixel = pixels[*iptr]; | pixel = pixels[*iptr]; |
for (i = 0, px = pixel; i < sizeof(unsigned long); | for (i = 0, px = pixel; i < sizeof(unsigned long); |
i++, px >>= 8) | i++, px >>= 8) |
|
|
{ | { |
unsigned char *data; | unsigned char *data; |
unsigned int *iptr; | unsigned int *iptr; |
int y; |
unsigned int y; |
Pixel pixel; | Pixel pixel; |
| |
#ifdef WITHOUT_SPEEDUPS | #ifdef WITHOUT_SPEEDUPS |
| |
int x; |
unsigned int x; |
unsigned char *addr; | unsigned char *addr; |
| |
data = (unsigned char *) image->data; | data = (unsigned char *) image->data; |
|
|
| |
#else /* WITHOUT_SPEEDUPS */ | #else /* WITHOUT_SPEEDUPS */ |
| |
int bpl = image->bytes_per_line; |
unsigned int bpl = image->bytes_per_line; |
unsigned char *data_ptr, *max_data; | unsigned char *data_ptr, *max_data; |
| |
data = (unsigned char *) image->data; | data = (unsigned char *) image->data; |
|
|
{ | { |
unsigned char *data; | unsigned char *data; |
unsigned int *iptr; | unsigned int *iptr; |
int y; |
unsigned int y; |
| |
#ifdef WITHOUT_SPEEDUPS | #ifdef WITHOUT_SPEEDUPS |
| |
int x; |
unsigned int x; |
unsigned char *addr; | unsigned char *addr; |
| |
data = (unsigned char *) image->data; | data = (unsigned char *) image->data; |
|
|
| |
Pixel pixel; | Pixel pixel; |
| |
int bpl = image->bytes_per_line; |
unsigned int bpl = image->bytes_per_line; |
unsigned char *data_ptr, *max_data; | unsigned char *data_ptr, *max_data; |
| |
data = (unsigned char *) image->data; | data = (unsigned char *) image->data; |
|
|
{ | { |
char *data; | char *data; |
unsigned int *iptr; | unsigned int *iptr; |
int y; |
unsigned int y; |
| |
#ifdef WITHOUT_SPEEDUPS | #ifdef WITHOUT_SPEEDUPS |
| |
int x; |
unsigned int x; |
| |
data = image->data; | data = image->data; |
iptr = pixelindex; | iptr = pixelindex; |
|
|
| |
#else /* WITHOUT_SPEEDUPS */ | #else /* WITHOUT_SPEEDUPS */ |
| |
int bpl = image->bytes_per_line; |
unsigned int bpl = image->bytes_per_line; |
char *data_ptr, *max_data; | char *data_ptr, *max_data; |
| |
data = image->data; | data = image->data; |
|
|
PutImagePixels(image, width, height, pixelindex, pixels); | PutImagePixels(image, width, height, pixelindex, pixels); |
else { | else { |
unsigned int *iptr; | unsigned int *iptr; |
int y; |
unsigned int y; |
char *data; | char *data; |
| |
#ifdef WITHOUT_SPEEDUPS | #ifdef WITHOUT_SPEEDUPS |
| |
int x; |
unsigned int x; |
| |
data = image->data; | data = image->data; |
iptr = pixelindex; | iptr = pixelindex; |
|
|
Pixel px; | Pixel px; |
int nbytes; | int nbytes; |
| |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8) | for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8) |
((unsigned char *)&pixel)[i] = px; | ((unsigned char *)&pixel)[i] = px; |
src = &ximage->data[XYINDEX(x, y, ximage)]; | src = &ximage->data[XYINDEX(x, y, ximage)]; |
|
|
register int i; | register int i; |
register char *data; | register char *data; |
Pixel px; | Pixel px; |
int nbytes, ibpp; |
unsigned int nbytes, ibpp; |
|
|
|
if(x < 0 || y < 0) |
|
return 0; |
| |
ibpp = ximage->bits_per_pixel; | ibpp = ximage->bits_per_pixel; |
if (ximage->depth == 4) | if (ximage->depth == 4) |
|
|
{ | { |
unsigned char *addr; | unsigned char *addr; |
| |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; | addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; |
*((unsigned long *)addr) = pixel; | *((unsigned long *)addr) = pixel; |
return 1; | return 1; |
|
|
{ | { |
unsigned char *addr; | unsigned char *addr; |
| |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; | addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; |
addr[0] = pixel >> 24; | addr[0] = pixel >> 24; |
addr[1] = pixel >> 16; | addr[1] = pixel >> 16; |
|
|
{ | { |
unsigned char *addr; | unsigned char *addr; |
| |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; | addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; |
addr[3] = pixel >> 24; | addr[3] = pixel >> 24; |
addr[2] = pixel >> 16; | addr[2] = pixel >> 16; |
|
|
{ | { |
unsigned char *addr; | unsigned char *addr; |
| |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; | addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; |
addr[0] = pixel >> 8; | addr[0] = pixel >> 8; |
addr[1] = pixel; | addr[1] = pixel; |
|
|
{ | { |
unsigned char *addr; | unsigned char *addr; |
| |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; | addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; |
addr[1] = pixel >> 8; | addr[1] = pixel >> 8; |
addr[0] = pixel; | addr[0] = pixel; |
|
|
int y; | int y; |
unsigned long pixel; | unsigned long pixel; |
{ | { |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
ximage->data[ZINDEX8(x, y, ximage)] = pixel; | ximage->data[ZINDEX8(x, y, ximage)] = pixel; |
return 1; | return 1; |
} | } |
|
|
int y; | int y; |
unsigned long pixel; | unsigned long pixel; |
{ | { |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
if (pixel & 1) | if (pixel & 1) |
ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7); | ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7); |
else | else |
|
|
int y; | int y; |
unsigned long pixel; | unsigned long pixel; |
{ | { |
|
if(x < 0 || y < 0) |
|
return 0; |
|
|
if (pixel & 1) | if (pixel & 1) |
ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7); | ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7); |
else | else |
|
|
/* function call in case of error, frees only locally allocated variables */ | /* function call in case of error, frees only locally allocated variables */ |
#undef RETURN | #undef RETURN |
#define RETURN(status) \ | #define RETURN(status) \ |
|
do \ |
{ \ | { \ |
if (USE_HASHTABLE) xpmHashTableFree(&hashtable); \ | if (USE_HASHTABLE) xpmHashTableFree(&hashtable); \ |
if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ | if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ |
|
|
if (alloc_pixels) XpmFree(alloc_pixels); \ | if (alloc_pixels) XpmFree(alloc_pixels); \ |
if (used_pixels) XpmFree(used_pixels); \ | if (used_pixels) XpmFree(used_pixels); \ |
return(status); \ | return(status); \ |
} |
} while(0) |
| |
/* | /* |
* This function parses an Xpm file or data and directly create an XImage | * This function parses an Xpm file or data and directly create an XImage |
|
|
xpmGetCmt(data, &colors_cmt); | xpmGetCmt(data, &colors_cmt); |
| |
/* malloc pixels index tables */ | /* malloc pixels index tables */ |
if (ncolors >= SIZE_MAX / sizeof(Pixel)) |
if (ncolors >= UINT_MAX / sizeof(Pixel)) |
return XpmNoMemory; |
RETURN(XpmNoMemory); |
| |
image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); | image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); |
if (!image_pixels) | if (!image_pixels) |
|
|
* free the hastable | * free the hastable |
*/ | */ |
if (ErrorStatus != XpmSuccess) | if (ErrorStatus != XpmSuccess) |
RETURN(ErrorStatus) |
RETURN(ErrorStatus); |
else if (USE_HASHTABLE) | else if (USE_HASHTABLE) |
xpmHashTableFree(&hashtable); | xpmHashTableFree(&hashtable); |
| |
|
|
/* | /* |
* parse extensions | * parse extensions |
*/ | */ |
if (info && (info->valuemask & XpmReturnExtensions)) |
if (info && (info->valuemask & XpmReturnExtensions)) { |
if (extensions) { | if (extensions) { |
ErrorStatus = xpmParseExtensions(data, &info->extensions, | ErrorStatus = xpmParseExtensions(data, &info->extensions, |
&info->nextensions); | &info->nextensions); |
|
|
info->extensions = NULL; | info->extensions = NULL; |
info->nextensions = 0; | info->nextensions = 0; |
} | } |
|
} |
/* | /* |
* store found informations in the XpmImage structure | * store found informations in the XpmImage structure |
*/ | */ |
|
|
| |
/* array of pointers malloced by need */ | /* array of pointers malloced by need */ |
unsigned short *cidx[256]; | unsigned short *cidx[256]; |
int char1; |
unsigned int char1; |
| |
if (ncolors > 256) | if (ncolors > 256) |
return (XpmFileInvalid); | return (XpmFileInvalid); |
| |
bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ | bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ |
for (a = 0; a < ncolors; a++) { | for (a = 0; a < ncolors; a++) { |
char1 = colorTable[a].string[0]; |
char1 = (unsigned char) colorTable[a].string[0]; |
if (cidx[char1] == NULL) { /* get new memory */ | if (cidx[char1] == NULL) { /* get new memory */ |
cidx[char1] = (unsigned short *) | cidx[char1] = (unsigned short *) |
XpmCalloc(256, sizeof(unsigned short)); | XpmCalloc(256, sizeof(unsigned short)); |
|
|
int cc1 = xpmGetC(data); | int cc1 = xpmGetC(data); |
if (cc1 > 0 && cc1 < 256) { | if (cc1 > 0 && cc1 < 256) { |
int cc2 = xpmGetC(data); | int cc2 = xpmGetC(data); |
if (cc2 > 0 && cc2 < 256 && cidx[cc1][cc2] != 0) { |
if (cc2 > 0 && cc2 < 256 && cidx[cc1] && cidx[cc1][cc2] != 0) { |
#ifndef FOR_MSW | #ifndef FOR_MSW |
XPutPixel(image, x, y, | XPutPixel(image, x, y, |
image_pixels[cidx[cc1][cc2] - 1]); | image_pixels[cidx[cc1][cc2] - 1]); |
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
| |
/* 3.2 backward compatibility code */ | /* 3.2 backward compatibility code */ |
LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors, | LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors, |
XpmColor ***oldct)); | XpmColor ***oldct)); |
| |
LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors)); |
LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, unsigned int ncolors)); |
| |
/* | /* |
* Create a colortable compatible with the old style colortable | * Create a colortable compatible with the old style colortable |
|
|
XpmColor ***oldct; | XpmColor ***oldct; |
{ | { |
XpmColor **colorTable, **color; | XpmColor **colorTable, **color; |
int a; |
unsigned int a; |
| |
if (ncolors >= SIZE_MAX / sizeof(XpmColor *)) |
if (ncolors >= UINT_MAX / sizeof(XpmColor *)) |
return XpmNoMemory; | return XpmNoMemory; |
| |
colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *)); | colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *)); |
|
|
static void | static void |
FreeOldColorTable(colorTable, ncolors) | FreeOldColorTable(colorTable, ncolors) |
XpmColor **colorTable; | XpmColor **colorTable; |
int ncolors; |
unsigned int ncolors; |
{ | { |
int a, b; |
unsigned int a, b; |
XpmColor **color; | XpmColor **color; |
char **sptr; | char **sptr; |
| |
|
|
XpmExtension *ext; | XpmExtension *ext; |
char **sptr; | char **sptr; |
| |
if (extensions) { |
if (extensions && nextensions > 0) { |
for (i = 0, ext = extensions; i < nextensions; i++, ext++) { | for (i = 0, ext = extensions; i < nextensions; i++, ext++) { |
if (ext->name) | if (ext->name) |
XpmFree(ext->name); | XpmFree(ext->name); |
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
#include <sys/stat.h> | #include <sys/stat.h> |
#include <sys/param.h> | #include <sys/param.h> |
|
|
/* | /* |
* open the given file to be read as an xpmData which is returned. | * open the given file to be read as an xpmData which is returned. |
*/ | */ |
|
#ifndef NO_ZPIPE |
|
FILE *s_popen(char *cmd, const char *type); |
|
#else |
|
# define s_popen popen |
|
#endif |
|
|
static int | static int |
OpenReadFile(filename, mdata) | OpenReadFile(filename, mdata) |
char *filename; | char *filename; |
|
|
mdata->type = XPMFILE; | mdata->type = XPMFILE; |
} else { | } else { |
#ifndef NO_ZPIPE | #ifndef NO_ZPIPE |
int len = strlen(filename); |
size_t len = strlen(filename); |
|
|
|
if(len == 0 || |
|
filename[len-1] == '/') |
|
return(XpmOpenFailed); |
if ((len > 2) && !strcmp(".Z", filename + (len - 2))) { | if ((len > 2) && !strcmp(".Z", filename + (len - 2))) { |
mdata->type = XPMPIPE; | mdata->type = XPMPIPE; |
sprintf(buf, "uncompress -c \"%s\"", filename); |
snprintf(buf, sizeof(buf), "uncompress -c \"%s\"", filename); |
if (!(mdata->stream.file = popen(buf, "r"))) |
if (!(mdata->stream.file = s_popen(buf, "r"))) |
return (XpmOpenFailed); | return (XpmOpenFailed); |
| |
} else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) { | } else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) { |
mdata->type = XPMPIPE; | mdata->type = XPMPIPE; |
sprintf(buf, "gunzip -qc \"%s\"", filename); |
snprintf(buf, sizeof(buf), "gunzip -qc \"%s\"", filename); |
if (!(mdata->stream.file = popen(buf, "r"))) |
if (!(mdata->stream.file = s_popen(buf, "r"))) |
return (XpmOpenFailed); | return (XpmOpenFailed); |
| |
} else { | } else { |
|
|
if (!(compressfile = (char *) XpmMalloc(len + 4))) | if (!(compressfile = (char *) XpmMalloc(len + 4))) |
return (XpmNoMemory); | return (XpmNoMemory); |
| |
sprintf(compressfile, "%s.Z", filename); |
snprintf(compressfile, len+4, "%s.Z", filename); |
if (!stat(compressfile, &status)) { | if (!stat(compressfile, &status)) { |
sprintf(buf, "uncompress -c \"%s\"", compressfile); |
snprintf(buf, sizeof(buf), "uncompress -c \"%s\"", compressfile); |
if (!(mdata->stream.file = popen(buf, "r"))) { |
if (!(mdata->stream.file = s_popen(buf, "r"))) { |
XpmFree(compressfile); | XpmFree(compressfile); |
return (XpmOpenFailed); | return (XpmOpenFailed); |
} | } |
mdata->type = XPMPIPE; | mdata->type = XPMPIPE; |
} else { | } else { |
sprintf(compressfile, "%s.gz", filename); |
snprintf(compressfile, len+4, "%s.gz", filename); |
if (!stat(compressfile, &status)) { | if (!stat(compressfile, &status)) { |
sprintf(buf, "gunzip -c \"%s\"", compressfile); |
snprintf(buf, sizeof(buf), "gunzip -c \"%s\"", compressfile); |
if (!(mdata->stream.file = popen(buf, "r"))) { |
if (!(mdata->stream.file = s_popen(buf, "r"))) { |
XpmFree(compressfile); | XpmFree(compressfile); |
return (XpmOpenFailed); | return (XpmOpenFailed); |
} | } |
|
|
break; | break; |
#ifndef NO_ZPIPE | #ifndef NO_ZPIPE |
case XPMPIPE: | case XPMPIPE: |
pclose(mdata->stream.file); |
fclose(mdata->stream.file); |
break; | break; |
#endif | #endif |
} | } |
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
| |
LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size, | LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size, |
XpmColor *colors, unsigned int ncolors, | XpmColor *colors, unsigned int ncolors, |
unsigned int cpp)); | unsigned int cpp)); |
| |
LFUNC(CreatePixels, void, (char **dataptr, unsigned int width, |
LFUNC(CreatePixels, void, (char **dataptr, unsigned int data_size, |
|
unsigned int width, |
unsigned int height, unsigned int cpp, | unsigned int height, unsigned int cpp, |
unsigned int *pixels, XpmColor *colors)); | unsigned int *pixels, XpmColor *colors)); |
| |
|
|
unsigned int *ext_size, | unsigned int *ext_size, |
unsigned int *ext_nlines)); | unsigned int *ext_nlines)); |
| |
LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset, |
LFUNC(CreateExtensions, void, (char **dataptr, unsigned int data_size, |
|
unsigned int offset, |
XpmExtension *ext, unsigned int num, | XpmExtension *ext, unsigned int num, |
unsigned int ext_nlines)); | unsigned int ext_nlines)); |
| |
|
|
| |
#undef RETURN | #undef RETURN |
#define RETURN(status) \ | #define RETURN(status) \ |
|
do \ |
{ \ | { \ |
if (header) { \ | if (header) { \ |
for (l = 0; l < header_nlines; l++) \ | for (l = 0; l < header_nlines; l++) \ |
|
|
XpmFree(header); \ | XpmFree(header); \ |
} \ | } \ |
return(status); \ | return(status); \ |
} |
} while(0) |
| |
int | int |
XpmCreateDataFromXpmImage(data_return, image, info) | XpmCreateDataFromXpmImage(data_return, image, info) |
|
|
* alloc a temporary array of char pointer for the header section which | * alloc a temporary array of char pointer for the header section which |
* is the hints line + the color table lines | * is the hints line + the color table lines |
*/ | */ |
header_nlines = 1 + image->ncolors; |
header_nlines = 1 + image->ncolors; /* this may wrap and/or become 0 */ |
|
|
|
/* 2nd check superfluous if we do not need header_nlines any further */ |
|
if(header_nlines <= image->ncolors || |
|
header_nlines >= UINT_MAX / sizeof(char *)) |
|
return(XpmNoMemory); |
|
|
header_size = sizeof(char *) * header_nlines; | header_size = sizeof(char *) * header_nlines; |
if (header_size >= SIZE_MAX / sizeof(char *)) |
if (header_size >= UINT_MAX / sizeof(char *)) |
return (XpmNoMemory); | return (XpmNoMemory); |
header = (char **) XpmCalloc(header_size, sizeof(char *)); |
header = (char **) XpmCalloc(header_size, sizeof(char *)); /* can we trust image->ncolors */ |
if (!header) | if (!header) |
return (XpmNoMemory); | return (XpmNoMemory); |
| |
|
|
| |
/* now we know the size needed, alloc the data and copy the header lines */ | /* now we know the size needed, alloc the data and copy the header lines */ |
offset = image->width * image->cpp + 1; | offset = image->width * image->cpp + 1; |
data_size = header_size + (image->height + ext_nlines) * sizeof(char *) |
|
+ image->height * offset + ext_size; |
if(offset <= image->width || offset <= image->cpp) |
|
RETURN(XpmNoMemory); |
|
|
|
if( (image->height + ext_nlines) >= UINT_MAX / sizeof(char *)) |
|
RETURN(XpmNoMemory); |
|
data_size = (image->height + ext_nlines) * sizeof(char *); |
|
|
|
if (image->height > UINT_MAX / offset || |
|
image->height * offset > UINT_MAX - data_size) |
|
RETURN(XpmNoMemory); |
|
data_size += image->height * offset; |
|
|
|
if( (header_size + ext_size) >= (UINT_MAX - data_size) ) |
|
RETURN(XpmNoMemory); |
|
data_size += header_size + ext_size; |
| |
data = (char **) XpmMalloc(data_size); | data = (char **) XpmMalloc(data_size); |
if (!data) | if (!data) |
|
|
| |
data_nlines = header_nlines + image->height + ext_nlines; | data_nlines = header_nlines + image->height + ext_nlines; |
*data = (char *) (data + data_nlines); | *data = (char *) (data + data_nlines); |
|
|
|
/* can header have less elements then n suggests? */ |
n = image->ncolors; | n = image->ncolors; |
for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) { |
for (l = 0, sptr = data, sptr2 = header; l <= n && sptr && sptr2; l++, sptr++, sptr2++) { |
strcpy(*sptr, *sptr2); | strcpy(*sptr, *sptr2); |
*(sptr + 1) = *sptr + strlen(*sptr2) + 1; | *(sptr + 1) = *sptr + strlen(*sptr2) + 1; |
} | } |
|
|
data[header_nlines] = (char *) data + header_size | data[header_nlines] = (char *) data + header_size |
+ (image->height + ext_nlines) * sizeof(char *); | + (image->height + ext_nlines) * sizeof(char *); |
| |
CreatePixels(data + header_nlines, image->width, image->height, |
CreatePixels(data + header_nlines, data_size-header_nlines, image->width, image->height, |
image->cpp, image->data, image->colorTable); | image->cpp, image->data, image->colorTable); |
| |
/* print extensions */ | /* print extensions */ |
if (extensions) | if (extensions) |
CreateExtensions(data + header_nlines + image->height - 1, offset, |
CreateExtensions(data + header_nlines + image->height - 1, |
|
data_size - header_nlines - image->height + 1, offset, |
info->extensions, info->nextensions, | info->extensions, info->nextensions, |
ext_nlines); | ext_nlines); |
| |
|
|
char *s, *s2; | char *s, *s2; |
char **defaults; | char **defaults; |
| |
|
/* can ncolors be trusted here? */ |
for (a = 0; a < ncolors; a++, colors++, dataptr++) { | for (a = 0; a < ncolors; a++, colors++, dataptr++) { |
| |
defaults = (char **) colors; | defaults = (char **) colors; |
|
if(sizeof(buf) <= cpp) |
|
return(XpmNoMemory); |
strncpy(buf, *defaults++, cpp); | strncpy(buf, *defaults++, cpp); |
s = buf + cpp; | s = buf + cpp; |
| |
|
if(sizeof(buf) <= (s-buf)) |
|
return XpmNoMemory; |
|
|
for (key = 1; key <= NKEYS; key++, defaults++) { | for (key = 1; key <= NKEYS; key++, defaults++) { |
if (s2 = *defaults) { | if (s2 = *defaults) { |
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
s += | s += |
#endif | #endif |
sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); |
/* assume C99 compliance */ |
|
snprintf(s, sizeof(buf)-(s-buf), "\t%s %s", xpmColorKeys[key - 1], s2); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
s += strlen(s); | s += strlen(s); |
#endif | #endif |
|
/* does s point out-of-bounds? */ |
|
if(sizeof(buf) < (s-buf)) |
|
return XpmNoMemory; |
} | } |
} | } |
|
/* what about using strdup()? */ |
l = s - buf + 1; | l = s - buf + 1; |
s = (char *) XpmMalloc(l); | s = (char *) XpmMalloc(l); |
if (!s) | if (!s) |
|
|
} | } |
| |
static void | static void |
CreatePixels(dataptr, width, height, cpp, pixels, colors) |
CreatePixels(dataptr, data_size, width, height, cpp, pixels, colors) |
char **dataptr; | char **dataptr; |
|
unsigned int data_size; |
unsigned int width; | unsigned int width; |
unsigned int height; | unsigned int height; |
unsigned int cpp; | unsigned int cpp; |
|
|
char *s; | char *s; |
unsigned int x, y, h, offset; | unsigned int x, y, h, offset; |
| |
|
if(height <= 1) |
|
return; |
|
|
h = height - 1; | h = height - 1; |
|
|
offset = width * cpp + 1; | offset = width * cpp + 1; |
|
|
|
if(offset <= width || offset <= cpp) |
|
return; |
|
|
|
/* why trust h? */ |
for (y = 0; y < h; y++, dataptr++) { | for (y = 0; y < h; y++, dataptr++) { |
s = *dataptr; | s = *dataptr; |
|
/* why trust width? */ |
for (x = 0; x < width; x++, pixels++) { | for (x = 0; x < width; x++, pixels++) { |
strncpy(s, colors[*pixels].string, cpp); |
if(cpp > (data_size - (s - *dataptr))) |
|
return; |
|
strncpy(s, colors[*pixels].string, cpp); /* why trust pixel? */ |
s += cpp; | s += cpp; |
} | } |
*s = '\0'; | *s = '\0'; |
|
if(offset > data_size) |
|
return; |
*(dataptr + 1) = *dataptr + offset; | *(dataptr + 1) = *dataptr + offset; |
} | } |
/* duplicate some code to avoid a test in the loop */ | /* duplicate some code to avoid a test in the loop */ |
s = *dataptr; | s = *dataptr; |
|
/* why trust width? */ |
for (x = 0; x < width; x++, pixels++) { | for (x = 0; x < width; x++, pixels++) { |
strncpy(s, colors[*pixels].string, cpp); |
if(cpp > data_size - (s - *dataptr)) |
|
return; |
|
strncpy(s, colors[*pixels].string, cpp); /* why should we trust *pixel? */ |
s += cpp; | s += cpp; |
} | } |
*s = '\0'; | *s = '\0'; |
|
|
} | } |
| |
static void | static void |
CreateExtensions(dataptr, offset, ext, num, ext_nlines) |
CreateExtensions(dataptr, data_size, offset, ext, num, ext_nlines) |
char **dataptr; | char **dataptr; |
|
unsigned int data_size; |
unsigned int offset; | unsigned int offset; |
XpmExtension *ext; | XpmExtension *ext; |
unsigned int num; | unsigned int num; |
|
|
dataptr++; | dataptr++; |
a = 0; | a = 0; |
for (x = 0; x < num; x++, ext++) { | for (x = 0; x < num; x++, ext++) { |
sprintf(*dataptr, "XPMEXT %s", ext->name); |
snprintf(*dataptr, data_size, "XPMEXT %s", ext->name); |
a++; | a++; |
if (a < ext_nlines) | if (a < ext_nlines) |
*(dataptr + 1) = *dataptr + strlen(ext->name) + 8; | *(dataptr + 1) = *dataptr + strlen(ext->name) + 8; |
dataptr++; | dataptr++; |
b = ext->nlines; |
b = ext->nlines; /* can we trust these values? */ |
for (y = 0, line = ext->lines; y < b; y++, line++) { | for (y = 0, line = ext->lines; y < b; y++, line++) { |
strcpy(*dataptr, *line); | strcpy(*dataptr, *line); |
a++; | a++; |
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
|
|
#include "XpmI.h" | #include "XpmI.h" |
| |
LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size, | LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size, |
unsigned int *used_size, XpmColor *colors, | unsigned int *used_size, XpmColor *colors, |
unsigned int ncolors, unsigned int cpp)); | unsigned int ncolors, unsigned int cpp)); |
| |
LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size, |
LFUNC(WritePixels, void, (char *dataptr, unsigned int data_size, |
|
unsigned int *used_size, |
unsigned int width, unsigned int height, | unsigned int width, unsigned int height, |
unsigned int cpp, unsigned int *pixels, | unsigned int cpp, unsigned int *pixels, |
XpmColor *colors)); | XpmColor *colors)); |
| |
LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size, |
LFUNC(WriteExtensions, void, (char *dataptr, unsigned int data_size, |
|
unsigned int *used_size, |
XpmExtension *ext, unsigned int num)); | XpmExtension *ext, unsigned int num)); |
| |
LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num)); |
LFUNC(ExtensionsSize, unsigned int, (XpmExtension *ext, unsigned int num)); |
LFUNC(CommentsSize, int, (XpmInfo *info)); | LFUNC(CommentsSize, int, (XpmInfo *info)); |
| |
int | int |
|
|
| |
#undef RETURN | #undef RETURN |
#define RETURN(status) \ | #define RETURN(status) \ |
|
do \ |
{ \ | { \ |
if (ptr) \ | if (ptr) \ |
XpmFree(ptr); \ | XpmFree(ptr); \ |
return(status); \ | return(status); \ |
} |
} while(0) |
| |
int | int |
XpmCreateBufferFromXpmImage(buffer_return, image, info) | XpmCreateBufferFromXpmImage(buffer_return, image, info) |
|
|
unsigned int cmts, extensions, ext_size = 0; | unsigned int cmts, extensions, ext_size = 0; |
unsigned int l, cmt_size = 0; | unsigned int l, cmt_size = 0; |
char *ptr = NULL, *p; | char *ptr = NULL, *p; |
unsigned int ptr_size, used_size; |
unsigned int ptr_size, used_size, tmp; |
| |
*buffer_return = NULL; | *buffer_return = NULL; |
| |
|
|
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
used_size = strlen(buf); | used_size = strlen(buf); |
#endif | #endif |
ptr_size = used_size + ext_size + cmt_size + 1; |
ptr_size = used_size + ext_size + cmt_size + 1; /* ptr_size can't be 0 */ |
|
if(ptr_size <= used_size || |
|
ptr_size <= ext_size || |
|
ptr_size <= cmt_size) |
|
{ |
|
return XpmNoMemory; |
|
} |
ptr = (char *) XpmMalloc(ptr_size); | ptr = (char *) XpmMalloc(ptr_size); |
if (!ptr) | if (!ptr) |
return XpmNoMemory; | return XpmNoMemory; |
|
|
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
used_size += | used_size += |
#endif | #endif |
sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt); |
snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->hints_cmt); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
used_size += strlen(info->hints_cmt) + 5; | used_size += strlen(info->hints_cmt) + 5; |
#endif | #endif |
|
|
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
l += | l += |
#endif | #endif |
sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot); |
snprintf(buf + l, sizeof(buf)-l, " %d %d", info->x_hotspot, info->y_hotspot); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
l = strlen(buf); | l = strlen(buf); |
#endif | #endif |
|
|
l = strlen(buf); | l = strlen(buf); |
#endif | #endif |
ptr_size += l; | ptr_size += l; |
|
if(ptr_size <= l) |
|
RETURN(XpmNoMemory); |
p = (char *) XpmRealloc(ptr, ptr_size); | p = (char *) XpmRealloc(ptr, ptr_size); |
if (!p) | if (!p) |
RETURN(XpmNoMemory); | RETURN(XpmNoMemory); |
|
|
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
used_size += | used_size += |
#endif | #endif |
sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt); |
snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->colors_cmt); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
used_size += strlen(info->colors_cmt) + 5; | used_size += strlen(info->colors_cmt) + 5; |
#endif | #endif |
|
|
* 4 = 1 (for '"') + 3 (for '",\n') | * 4 = 1 (for '"') + 3 (for '",\n') |
* 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n') | * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n') |
*/ | */ |
ptr_size += image->height * (image->width * image->cpp + 4) + 1; |
if(image->width > UINT_MAX / image->cpp || |
|
(tmp = image->width * image->cpp + 4) <= 4 || |
|
image->height > UINT_MAX / tmp || |
|
(tmp = image->height * tmp + 1) <= 1 || |
|
(ptr_size += tmp) <= tmp) |
|
RETURN(XpmNoMemory); |
| |
p = (char *) XpmRealloc(ptr, ptr_size); | p = (char *) XpmRealloc(ptr, ptr_size); |
if (!p) | if (!p) |
|
|
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
used_size += | used_size += |
#endif | #endif |
sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt); |
snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->pixels_cmt); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
used_size += strlen(info->pixels_cmt) + 5; | used_size += strlen(info->pixels_cmt) + 5; |
#endif | #endif |
} | } |
WritePixels(ptr + used_size, &used_size, image->width, image->height, |
WritePixels(ptr + used_size, ptr_size - used_size, &used_size, image->width, image->height, |
image->cpp, image->data, image->colorTable); | image->cpp, image->data, image->colorTable); |
| |
/* print extensions */ | /* print extensions */ |
if (extensions) | if (extensions) |
WriteExtensions(ptr + used_size, &used_size, |
WriteExtensions(ptr + used_size, ptr_size-used_size, &used_size, |
info->extensions, info->nextensions); | info->extensions, info->nextensions); |
| |
/* close the array */ | /* close the array */ |
|
|
return (XpmSuccess); | return (XpmSuccess); |
} | } |
| |
|
|
static int | static int |
WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp) | WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp) |
char **dataptr; | char **dataptr; |
|
|
unsigned int ncolors; | unsigned int ncolors; |
unsigned int cpp; | unsigned int cpp; |
{ | { |
char buf[BUFSIZ]; |
char buf[BUFSIZ] = {0}; |
unsigned int a, key, l; | unsigned int a, key, l; |
char *s, *s2; | char *s, *s2; |
char **defaults; | char **defaults; |
|
|
| |
defaults = (char **) colors; | defaults = (char **) colors; |
s = buf + 1; | s = buf + 1; |
|
if(cpp > (sizeof(buf) - (s-buf))) |
|
return(XpmNoMemory); |
strncpy(s, *defaults++, cpp); | strncpy(s, *defaults++, cpp); |
s += cpp; | s += cpp; |
| |
for (key = 1; key <= NKEYS; key++, defaults++) { | for (key = 1; key <= NKEYS; key++, defaults++) { |
if (s2 = *defaults) { |
if ((s2 = *defaults)) { |
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
s += | s += |
#endif | #endif |
sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); |
/* assume C99 compliance */ |
|
snprintf(s, sizeof(buf) - (s-buf), "\t%s %s", xpmColorKeys[key - 1], s2); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
s += strlen(s); | s += strlen(s); |
#endif | #endif |
|
/* now let's check if s points out-of-bounds */ |
|
if((s-buf) > sizeof(buf)) |
|
return(XpmNoMemory); |
} | } |
} | } |
|
if(sizeof(buf) - (s-buf) < 4) |
|
return(XpmNoMemory); |
strcpy(s, "\",\n"); | strcpy(s, "\",\n"); |
l = s + 3 - buf; | l = s + 3 - buf; |
|
if( *data_size >= UINT_MAX-l || |
|
*data_size + l <= *used_size || |
|
(*data_size + l - *used_size) <= sizeof(buf)) |
|
return(XpmNoMemory); |
s = (char *) XpmRealloc(*dataptr, *data_size + l); | s = (char *) XpmRealloc(*dataptr, *data_size + l); |
if (!s) | if (!s) |
return (XpmNoMemory); | return (XpmNoMemory); |
|
|
} | } |
| |
static void | static void |
WritePixels(dataptr, used_size, width, height, cpp, pixels, colors) |
WritePixels(dataptr, data_size, used_size, width, height, cpp, pixels, colors) |
char *dataptr; | char *dataptr; |
|
unsigned int data_size; |
unsigned int *used_size; | unsigned int *used_size; |
unsigned int width; | unsigned int width; |
unsigned int height; | unsigned int height; |
|
|
char *s = dataptr; | char *s = dataptr; |
unsigned int x, y, h; | unsigned int x, y, h; |
| |
|
if(height <= 1) |
|
return; |
|
|
h = height - 1; | h = height - 1; |
for (y = 0; y < h; y++) { | for (y = 0; y < h; y++) { |
*s++ = '"'; | *s++ = '"'; |
for (x = 0; x < width; x++, pixels++) { | for (x = 0; x < width; x++, pixels++) { |
strncpy(s, colors[*pixels].string, cpp); |
if(cpp >= (data_size - (s-dataptr))) |
|
return; |
|
strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? :-\ */ |
s += cpp; | s += cpp; |
} | } |
|
if((data_size - (s-dataptr)) < 4) |
|
return; |
strcpy(s, "\",\n"); | strcpy(s, "\",\n"); |
s += 3; | s += 3; |
} | } |
/* duplicate some code to avoid a test in the loop */ | /* duplicate some code to avoid a test in the loop */ |
*s++ = '"'; | *s++ = '"'; |
for (x = 0; x < width; x++, pixels++) { | for (x = 0; x < width; x++, pixels++) { |
strncpy(s, colors[*pixels].string, cpp); |
if(cpp >= (data_size - (s-dataptr))) |
|
return; |
|
strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? */ |
s += cpp; | s += cpp; |
} | } |
*s++ = '"'; | *s++ = '"'; |
*used_size += s - dataptr; | *used_size += s - dataptr; |
} | } |
| |
static int |
static unsigned int |
ExtensionsSize(ext, num) | ExtensionsSize(ext, num) |
XpmExtension *ext; | XpmExtension *ext; |
unsigned int num; | unsigned int num; |
|
|
char **line; | char **line; |
| |
size = 0; | size = 0; |
|
if(num == 0) |
|
return(0); /* ok? */ |
for (x = 0; x < num; x++, ext++) { | for (x = 0; x < num; x++, ext++) { |
/* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */ | /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */ |
size += strlen(ext->name) + 11; | size += strlen(ext->name) + 11; |
a = ext->nlines; |
a = ext->nlines; /* how can we trust ext->nlines to be not out-of-bounds? */ |
for (y = 0, line = ext->lines; y < a; y++, line++) | for (y = 0, line = ext->lines; y < a; y++, line++) |
/* 4 = 3 (for ',\n"') + 1 (for '"') */ | /* 4 = 3 (for ',\n"') + 1 (for '"') */ |
size += strlen(*line) + 4; | size += strlen(*line) + 4; |
} | } |
/* 13 is for ',\n"XPMENDEXT"' */ | /* 13 is for ',\n"XPMENDEXT"' */ |
|
if(size > UINT_MAX - 13) /* unlikely */ |
|
return(0); |
return size + 13; | return size + 13; |
} | } |
| |
static void | static void |
WriteExtensions(dataptr, used_size, ext, num) |
WriteExtensions(dataptr, data_size, used_size, ext, num) |
char *dataptr; | char *dataptr; |
|
unsigned int data_size; |
unsigned int *used_size; | unsigned int *used_size; |
XpmExtension *ext; | XpmExtension *ext; |
unsigned int num; | unsigned int num; |
|
|
| |
for (x = 0; x < num; x++, ext++) { | for (x = 0; x < num; x++, ext++) { |
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
s += 11 + |
s += |
#endif | #endif |
sprintf(s, ",\n\"XPMEXT %s\"", ext->name); |
snprintf(s, data_size - (s-dataptr), ",\n\"XPMEXT %s\"", ext->name); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
s += strlen(ext->name) + 11; | s += strlen(ext->name) + 11; |
#endif | #endif |
a = ext->nlines; | a = ext->nlines; |
for (y = 0, line = ext->lines; y < a; y++, line++) { | for (y = 0, line = ext->lines; y < a; y++, line++) { |
#ifndef VOID_SPRINTF | #ifndef VOID_SPRINTF |
s += 4 + |
s += |
#endif | #endif |
sprintf(s, ",\n\"%s\"", *line); |
snprintf(s, data_size - (s-dataptr), ",\n\"%s\"", *line); |
#ifdef VOID_SPRINTF | #ifdef VOID_SPRINTF |
s += strlen(*line) + 4; | s += strlen(*line) + 4; |
#endif | #endif |
} | } |
} | } |
strcpy(s, ",\n\"XPMENDEXT\""); |
strncpy(s, ",\n\"XPMENDEXT\"", data_size - (s-dataptr)-1); |
*used_size += s - dataptr + 13; | *used_size += s - dataptr + 13; |
} | } |
| |
|
|
int size = 0; | int size = 0; |
| |
/* 5 = 2 (for "/_*") + 3 (for "*_/\n") */ | /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */ |
|
/* wrap possible but *very* unlikely */ |
if (info->hints_cmt) | if (info->hints_cmt) |
size += 5 + strlen(info->hints_cmt); | size += 5 + strlen(info->hints_cmt); |
| |
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
/* Official version number */ | /* Official version number */ |
static char *RCS_Version = "$XpmVersion: 3.4i $"; | static char *RCS_Version = "$XpmVersion: 3.4i $"; |
| |
|
|
} | } |
ungetc(c, file); | ungetc(c, file); |
} | } |
return (n); |
return (n); /* this returns bytes read + 1 */ |
} | } |
| |
/* | /* |
|
|
{ | { |
if (!mdata->type) | if (!mdata->type) |
*cmt = NULL; | *cmt = NULL; |
else if (mdata->CommentLength) { |
else if (mdata->CommentLength != 0 && mdata->CommentLength < UINT_MAX - 1) { |
*cmt = (char *) XpmMalloc(mdata->CommentLength + 1); |
if( (*cmt = (char *) XpmMalloc(mdata->CommentLength + 1)) == NULL) |
|
return XpmNoMemory; |
strncpy(*cmt, mdata->Comment, mdata->CommentLength); | strncpy(*cmt, mdata->Comment, mdata->CommentLength); |
(*cmt)[mdata->CommentLength] = '\0'; | (*cmt)[mdata->CommentLength] = '\0'; |
mdata->CommentLength = 0; | mdata->CommentLength = 0; |
|
|
xpmParseHeader(mdata) | xpmParseHeader(mdata) |
xpmData *mdata; | xpmData *mdata; |
{ | { |
char buf[BUFSIZ]; |
char buf[BUFSIZ+1] = {0}; |
int l, n = 0; | int l, n = 0; |
| |
if (mdata->type) { | if (mdata->type) { |
|
|
XpmCrBufFrP.c XpmCrPFrBuf.c XpmRdFToDat.c XpmWrFFrP.c Xpmrgb.c \ | XpmCrBufFrP.c XpmCrPFrBuf.c XpmRdFToDat.c XpmWrFFrP.c Xpmrgb.c \ |
XpmCrDatFrI.c XpmCrPFrDat.c XpmRdFToI.c Xpmcreate.c Xpmscan.c \ | XpmCrDatFrI.c XpmCrPFrDat.c XpmRdFToI.c Xpmcreate.c Xpmscan.c \ |
XpmCrDatFrP.c XpmCrPFrI.c XpmRdFToP.c Xpmdata.c \ | XpmCrDatFrP.c XpmCrPFrI.c XpmRdFToP.c Xpmdata.c \ |
XpmCrIFrBuf.c XpmImage.c XpmWrFFrBuf.c Xpmhashtab.c |
XpmCrIFrBuf.c XpmImage.c XpmWrFFrBuf.c Xpmhashtab.c \ |
|
s_popen.c |
| |
#if UseLocalRegex | #if UseLocalRegex |
REGEX_SRCS = regexp.c | REGEX_SRCS = regexp.c |
|
|
XpmCrBufFrP.o XpmCrPFrBuf.o XpmRdFToDat.o XpmWrFFrP.o Xpmrgb.o \ | XpmCrBufFrP.o XpmCrPFrBuf.o XpmRdFToDat.o XpmWrFFrP.o Xpmrgb.o \ |
XpmCrDatFrI.o XpmCrPFrDat.o XpmRdFToI.o Xpmcreate.o Xpmscan.o \ | XpmCrDatFrI.o XpmCrPFrDat.o XpmRdFToI.o Xpmcreate.o Xpmscan.o \ |
XpmCrDatFrP.o XpmCrPFrI.o XpmRdFToP.o Xpmdata.o \ | XpmCrDatFrP.o XpmCrPFrI.o XpmRdFToP.o Xpmdata.o \ |
XpmCrIFrBuf.o XpmImage.o XpmWrFFrBuf.o Xpmhashtab.o |
XpmCrIFrBuf.o XpmImage.o XpmWrFFrBuf.o Xpmhashtab.o \ |
|
s_popen.o |
| |
#if UseLocalRegex | #if UseLocalRegex |
REGEX_OBJS = regexp.o | REGEX_OBJS = regexp.o |
|
|
#define xpmatoui _Xmxpmatoui | #define xpmatoui _Xmxpmatoui |
#define xpmDataTypes _XmxpmDataTypes | #define xpmDataTypes _XmxpmDataTypes |
#define xpmColorKeys _XmxpmColorKeys | #define xpmColorKeys _XmxpmColorKeys |
|
#define s_popen _Xms_popen |
| |
/* The following is the original XpmI.h header file, | /* The following is the original XpmI.h header file, |
except that it includes XpmP.h instead of xpm.h */ | except that it includes XpmP.h instead of xpm.h */ |
|
|
* lets try to solve include files | * lets try to solve include files |
*/ | */ |
| |
|
#include <sys/types.h> |
#include <stdio.h> | #include <stdio.h> |
#include <stdlib.h> | #include <stdlib.h> |
|
#include <limits.h> |
/* stdio.h doesn't declare popen on a Sequent DYNIX OS */ | /* stdio.h doesn't declare popen on a Sequent DYNIX OS */ |
#ifdef sequent | #ifdef sequent |
extern FILE *popen(); | extern FILE *popen(); |
|
|
* HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 | * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 |
*/ | */ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
#include <sys/stat.h> | #include <sys/stat.h> |
#if !defined(FOR_MSW) && !defined(WIN32) | #if !defined(FOR_MSW) && !defined(WIN32) |
|
|
char *filename; | char *filename; |
char **buffer_return; | char **buffer_return; |
{ | { |
int fd, fcheck, len; |
int fd, fcheck; |
|
off_t len; |
char *ptr; | char *ptr; |
struct stat stats; | struct stat stats; |
FILE *fp; | FILE *fp; |
|
|
close(fd); | close(fd); |
return XpmOpenFailed; | return XpmOpenFailed; |
} | } |
len = (int) stats.st_size; |
len = stats.st_size; |
ptr = (char *) XpmMalloc(len + 1); | ptr = (char *) XpmMalloc(len + 1); |
if (!ptr) { | if (!ptr) { |
fclose(fp); | fclose(fp); |
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
| |
int | int |
|
|
fcheck = fwrite(buffer, len, 1, fp); | fcheck = fwrite(buffer, len, 1, fp); |
fclose(fp); | fclose(fp); |
if (fcheck != 1) | if (fcheck != 1) |
return XpmOpenFailed; |
return XpmOpenFailed; /* maybe use a better return value */ |
| |
return XpmSuccess; | return XpmSuccess; |
} | } |
|
|
char *s1; | char *s1; |
{ | { |
char *s2; | char *s2; |
int l = strlen(s1) + 1; |
size_t l = strlen(s1) + 1; |
| |
if (s2 = (char *) XpmMalloc(l)) | if (s2 = (char *) XpmMalloc(l)) |
strcpy(s2, s1); | strcpy(s2, s1); |
|
|
* HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 | * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 |
*/ | */ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
| |
#define MAXPRINTABLE 92 /* number of printable ascii chars | #define MAXPRINTABLE 92 /* number of printable ascii chars |
* minus \ and " for string compat | * minus \ and " for string compat |
* and ? to avoid ANSI trigraphs. */ | * and ? to avoid ANSI trigraphs. */ |
|
/* " */ |
static char *printable = | static char *printable = |
" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ | " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ |
ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; | ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; |
|
|
/* function call in case of error, frees only locally allocated variables */ | /* function call in case of error, frees only locally allocated variables */ |
#undef RETURN | #undef RETURN |
#define RETURN(status) \ | #define RETURN(status) \ |
|
do \ |
{ \ | { \ |
if (pmap.pixelindex) XpmFree(pmap.pixelindex); \ | if (pmap.pixelindex) XpmFree(pmap.pixelindex); \ |
if (pmap.pixels) XpmFree(pmap.pixels); \ | if (pmap.pixels) XpmFree(pmap.pixels); \ |
if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \ | if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \ |
return(status); \ | return(status); \ |
} |
} while(0) |
| |
/* | /* |
* This function scans the given image and stores the found informations in | * This function scans the given image and stores the found informations in |
|
|
/* variables to return */ | /* variables to return */ |
PixelsMap pmap; | PixelsMap pmap; |
XpmColor *colorTable = NULL; | XpmColor *colorTable = NULL; |
int ErrorStatus; |
int ErrorStatus = 0; |
| |
/* calculation variables */ | /* calculation variables */ |
unsigned int width = 0; | unsigned int width = 0; |
|
|
else | else |
cpp = 0; | cpp = 0; |
| |
if ((height > 0 && width >= SIZE_MAX / height) || |
if ((height > 0 && width >= UINT_MAX / height) || |
width * height >= SIZE_MAX / sizeof(unsigned int)) |
width * height >= UINT_MAX / sizeof(unsigned int)) |
RETURN(XpmNoMemory); | RETURN(XpmNoMemory); |
pmap.pixelindex = | pmap.pixelindex = |
(unsigned int *) XpmCalloc(width * height, sizeof(unsigned int)); | (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int)); |
if (!pmap.pixelindex) | if (!pmap.pixelindex) |
RETURN(XpmNoMemory); | RETURN(XpmNoMemory); |
| |
if (pmap.size >= SIZE_MAX / sizeof(Pixel)) |
if (pmap.size >= UINT_MAX / sizeof(Pixel)) |
RETURN(XpmNoMemory); | RETURN(XpmNoMemory); |
| |
pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size); | pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size); |
|
|
* get rgb values and a string of char, and possibly a name for each | * get rgb values and a string of char, and possibly a name for each |
* color | * color |
*/ | */ |
if (pmap.ncolors >= SIZE_MAX / sizeof(XpmColor)) |
if (pmap.ncolors >= UINT_MAX / sizeof(XpmColor)) |
RETURN(XpmNoMemory); | RETURN(XpmNoMemory); |
colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor)); | colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor)); |
if (!colorTable) | if (!colorTable) |
|
|
| |
/* first get a character string */ | /* first get a character string */ |
a = 0; | a = 0; |
if (cpp >= SIZE_MAX - 1) |
if (cpp >= UINT_MAX - 1) |
return (XpmNoMemory); | return (XpmNoMemory); |
if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) | if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) |
return (XpmNoMemory); | return (XpmNoMemory); |
|
|
} | } |
| |
/* first get character strings and rgb values */ | /* first get character strings and rgb values */ |
if (ncolors >= SIZE_MAX / sizeof(XColor) || cpp >= SIZE_MAX - 1) |
if (ncolors >= UINT_MAX / sizeof(XColor) || cpp >= UINT_MAX - 1) |
return (XpmNoMemory); | return (XpmNoMemory); |
xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors); | xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors); |
if (!xcolors) | if (!xcolors) |
|
|
char *dst; | char *dst; |
unsigned int *iptr; | unsigned int *iptr; |
char *data; | char *data; |
int x, y, i; |
unsigned int x, y, i; |
int bits, depth, ibu, ibpp, offset; | int bits, depth, ibu, ibpp, offset; |
unsigned long lbt; | unsigned long lbt; |
Pixel pixel, px; | Pixel pixel, px; |
|
|
unsigned char *addr; | unsigned char *addr; |
unsigned char *data; | unsigned char *data; |
unsigned int *iptr; | unsigned int *iptr; |
int x, y; |
unsigned int x, y; |
unsigned long lbt; | unsigned long lbt; |
Pixel pixel; | Pixel pixel; |
int depth; | int depth; |
|
|
unsigned char *addr; | unsigned char *addr; |
unsigned char *data; | unsigned char *data; |
unsigned int *iptr; | unsigned int *iptr; |
int x, y; |
unsigned int x, y; |
unsigned long lbt; | unsigned long lbt; |
Pixel pixel; | Pixel pixel; |
int depth; | int depth; |
|
|
{ | { |
unsigned int *iptr; | unsigned int *iptr; |
unsigned char *data; | unsigned char *data; |
int x, y; |
unsigned int x, y; |
unsigned long lbt; | unsigned long lbt; |
Pixel pixel; | Pixel pixel; |
int depth; | int depth; |
|
|
int (*storeFunc) (); | int (*storeFunc) (); |
{ | { |
unsigned int *iptr; | unsigned int *iptr; |
int x, y; |
unsigned int x, y; |
char *data; | char *data; |
Pixel pixel; | Pixel pixel; |
int xoff, yoff, offset, bpl; | int xoff, yoff, offset, bpl; |
|
|
* HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 | * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 |
*/ | */ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
#include <ctype.h> | #include <ctype.h> |
|
#include <string.h> |
| |
#ifdef HAS_STRLCAT | #ifdef HAS_STRLCAT |
# define STRLCAT(dst, src, dstsize) { \ |
# define STRLCAT(dst, src, dstsize) do { \ |
if (strlcat(dst, src, dstsize) >= (dstsize)) \ | if (strlcat(dst, src, dstsize) >= (dstsize)) \ |
return (XpmFileInvalid); } |
return (XpmFileInvalid); } while(0) |
# define STRLCPY(dst, src, dstsize) { \ |
# define STRLCPY(dst, src, dstsize) do { \ |
if (strlcpy(dst, src, dstsize) >= (dstsize)) \ | if (strlcpy(dst, src, dstsize) >= (dstsize)) \ |
return (XpmFileInvalid); } |
return (XpmFileInvalid); } while(0) |
#else | #else |
# define STRLCAT(dst, src, dstsize) { \ |
# define STRLCAT(dst, src, dstsize) do { \ |
if ((strlen(dst) + strlen(src)) < (dstsize)) \ | if ((strlen(dst) + strlen(src)) < (dstsize)) \ |
strcat(dst, src); \ | strcat(dst, src); \ |
else return (XpmFileInvalid); } |
else return (XpmFileInvalid); } while(0) |
# define STRLCPY(dst, src, dstsize) { \ |
# define STRLCPY(dst, src, dstsize) do { \ |
if (strlen(src) < (dstsize)) \ | if (strlen(src) < (dstsize)) \ |
strcpy(dst, src); \ | strcpy(dst, src); \ |
else return (XpmFileInvalid); } |
else return (XpmFileInvalid); } while(0) |
#endif | #endif |
| |
LFUNC(ParsePixels, int, (xpmData *data, unsigned int width, | LFUNC(ParsePixels, int, (xpmData *data, unsigned int width, |
|
|
/* function call in case of error, frees only locally allocated variables */ | /* function call in case of error, frees only locally allocated variables */ |
#undef RETURN | #undef RETURN |
#define RETURN(status) \ | #define RETURN(status) \ |
|
do \ |
{ \ | { \ |
if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ | if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ |
if (pixelindex) XpmFree(pixelindex); \ | if (pixelindex) XpmFree(pixelindex); \ |
|
|
if (colors_cmt) XpmFree(colors_cmt); \ | if (colors_cmt) XpmFree(colors_cmt); \ |
if (pixels_cmt) XpmFree(pixels_cmt); \ | if (pixels_cmt) XpmFree(pixels_cmt); \ |
return(status); \ | return(status); \ |
} |
} while(0) |
| |
/* | /* |
* This function parses an Xpm file or data and store the found informations | * This function parses an Xpm file or data and store the found informations |
|
|
/* | /* |
* parse extensions | * parse extensions |
*/ | */ |
if (info && (info->valuemask & XpmReturnExtensions)) |
if (info && (info->valuemask & XpmReturnExtensions)) { |
if (extensions) { | if (extensions) { |
ErrorStatus = xpmParseExtensions(data, &info->extensions, | ErrorStatus = xpmParseExtensions(data, &info->extensions, |
&info->nextensions); | &info->nextensions); |
|
|
info->extensions = NULL; | info->extensions = NULL; |
info->nextensions = 0; | info->nextensions = 0; |
} | } |
|
} |
| |
/* | /* |
* store found informations in the XpmImage structure | * store found informations in the XpmImage structure |
|
|
char **defaults; | char **defaults; |
int ErrorStatus; | int ErrorStatus; |
| |
if (ncolors >= SIZE_MAX / sizeof(XpmColor)) |
if (ncolors >= UINT_MAX / sizeof(XpmColor)) |
return (XpmNoMemory); | return (XpmNoMemory); |
colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor)); | colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor)); |
if (!colorTable) | if (!colorTable) |
|
|
/* | /* |
* read pixel value | * read pixel value |
*/ | */ |
if (cpp >= SIZE_MAX - 1) { |
if (cpp >= UINT_MAX - 1) { |
xpmFreeColorTable(colorTable, ncolors); | xpmFreeColorTable(colorTable, ncolors); |
return (XpmNoMemory); | return (XpmNoMemory); |
} | } |
|
|
return (XpmFileInvalid); | return (XpmFileInvalid); |
} | } |
if (!lastwaskey) | if (!lastwaskey) |
STRLCAT(curbuf, " ", sizeof(curbuf)); /* append space */ |
STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */ |
buf[l] = '\0'; | buf[l] = '\0'; |
STRLCAT(curbuf, buf, sizeof(curbuf));/* append buf */ |
STRLCAT(curbuf, buf, sizeof(curbuf)); /* append buf */ |
lastwaskey = 0; | lastwaskey = 0; |
} | } |
} | } |
|
|
xpmFreeColorTable(colorTable, ncolors); | xpmFreeColorTable(colorTable, ncolors); |
return (XpmFileInvalid); | return (XpmFileInvalid); |
} | } |
len = strlen(curbuf) + 1; |
len = strlen(curbuf) + 1; /* integer overflow just theoretically possible */ |
s = defaults[curkey] = (char *) XpmMalloc(len); | s = defaults[curkey] = (char *) XpmMalloc(len); |
if (!s) { | if (!s) { |
xpmFreeColorTable(colorTable, ncolors); | xpmFreeColorTable(colorTable, ncolors); |
|
|
/* | /* |
* read pixel value | * read pixel value |
*/ | */ |
if (cpp >= SIZE_MAX - 1) { |
if (cpp >= UINT_MAX - 1) { |
xpmFreeColorTable(colorTable, ncolors); | xpmFreeColorTable(colorTable, ncolors); |
return (XpmNoMemory); | return (XpmNoMemory); |
} | } |
|
|
memcpy(s, curbuf, len); | memcpy(s, curbuf, len); |
color->c_color = s; | color->c_color = s; |
*curbuf = '\0'; /* reset curbuf */ | *curbuf = '\0'; /* reset curbuf */ |
if (a < ncolors - 1) |
if (a < ncolors - 1) /* can we trust ncolors -> leave data's bounds */ |
xpmNextString(data); /* get to the next string */ | xpmNextString(data); /* get to the next string */ |
} | } |
} | } |
|
|
xpmHashTable *hashtable; | xpmHashTable *hashtable; |
unsigned int **pixels; | unsigned int **pixels; |
{ | { |
unsigned int *iptr, *iptr2; |
unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */ |
unsigned int a, x, y; | unsigned int a, x, y; |
| |
if ((height > 0 && width >= SIZE_MAX / height) || |
if ((height > 0 && width >= UINT_MAX / height) || |
width * height >= SIZE_MAX / sizeof(unsigned int)) |
width * height >= UINT_MAX / sizeof(unsigned int)) |
return XpmNoMemory; | return XpmNoMemory; |
#ifndef FOR_MSW | #ifndef FOR_MSW |
iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height); | iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height); |
|
|
{ | { |
unsigned short colidx[256]; | unsigned short colidx[256]; |
| |
if (ncolors > 256) |
if (ncolors > 256) { |
return (XpmFileInvalid); | return (XpmFileInvalid); |
|
XpmFree(iptr2); /* found by Egbert Eich */ |
|
} |
| |
bzero((char *)colidx, 256 * sizeof(short)); | bzero((char *)colidx, 256 * sizeof(short)); |
for (a = 0; a < ncolors; a++) | for (a = 0; a < ncolors; a++) |
|
|
{ | { |
| |
/* free all allocated pointers at all exits */ | /* free all allocated pointers at all exits */ |
#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \ |
#define FREE_CIDX \ |
if (cidx[f]) XpmFree(cidx[f]);} |
do \ |
|
{ \ |
|
int f; for (f = 0; f < 256; f++) \ |
|
if (cidx[f]) XpmFree(cidx[f]); \ |
|
} while(0) |
| |
/* array of pointers malloced by need */ | /* array of pointers malloced by need */ |
unsigned short *cidx[256]; | unsigned short *cidx[256]; |
int char1; |
unsigned int char1; |
| |
bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ | bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ |
for (a = 0; a < ncolors; a++) { | for (a = 0; a < ncolors; a++) { |
char1 = colorTable[a].string[0]; |
char1 = (unsigned char) colorTable[a].string[0]; |
if (cidx[char1] == NULL) { /* get new memory */ | if (cidx[char1] == NULL) { /* get new memory */ |
cidx[char1] = (unsigned short *) | cidx[char1] = (unsigned short *) |
XpmCalloc(256, sizeof(unsigned short)); | XpmCalloc(256, sizeof(unsigned short)); |
|
|
int cc1 = xpmGetC(data); | int cc1 = xpmGetC(data); |
if (cc1 > 0 && cc1 < 256) { | if (cc1 > 0 && cc1 < 256) { |
int cc2 = xpmGetC(data); | int cc2 = xpmGetC(data); |
if (cc2 > 0 && cc2 < 256 && cidx[cc1][cc2] != 0) |
if (cc2 > 0 && cc2 < 256 && cidx[cc1] && cidx[cc1][cc2] != 0) |
*iptr = cidx[cc1][cc2] - 1; | *iptr = cidx[cc1][cc2] - 1; |
else { | else { |
FREE_CIDX; | FREE_CIDX; |
|
|
char *s; | char *s; |
char buf[BUFSIZ]; | char buf[BUFSIZ]; |
| |
if (cpp >= sizeof(buf)) |
if (cpp >= sizeof(buf)) { |
return (XpmFileInvalid); | return (XpmFileInvalid); |
|
XpmFree(iptr2); /* found by Egbert Eich */ |
|
} |
| |
buf[cpp] = '\0'; | buf[cpp] = '\0'; |
if (USE_HASHTABLE) { | if (USE_HASHTABLE) { |
|
|
xpmNextString(data); | xpmNextString(data); |
for (x = 0; x < width; x++, iptr++) { | for (x = 0; x < width; x++, iptr++) { |
for (a = 0, s = buf; a < cpp; a++, s++) | for (a = 0, s = buf; a < cpp; a++, s++) |
*s = xpmGetC(data); |
*s = xpmGetC(data); /* int assigned to char, not a problem here */ |
slot = xpmHashSlot(hashtable, buf); | slot = xpmHashSlot(hashtable, buf); |
if (!*slot) { /* no color matches */ | if (!*slot) { /* no color matches */ |
XpmFree(iptr2); | XpmFree(iptr2); |
|
|
xpmNextString(data); | xpmNextString(data); |
for (x = 0; x < width; x++, iptr++) { | for (x = 0; x < width; x++, iptr++) { |
for (a = 0, s = buf; a < cpp; a++, s++) | for (a = 0, s = buf; a < cpp; a++, s++) |
*s = xpmGetC(data); |
*s = xpmGetC(data); /* int assigned to char, not a problem here */ |
for (a = 0; a < ncolors; a++) | for (a = 0; a < ncolors; a++) |
if (!strcmp(colorTable[a].string, buf)) | if (!strcmp(colorTable[a].string, buf)) |
break; | break; |
|
|
while (!notstart && notend) { | while (!notstart && notend) { |
/* there starts an extension */ | /* there starts an extension */ |
ext = (XpmExtension *) | ext = (XpmExtension *) |
XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); |
XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); /* can the loop be forced to iterate often enough to make "(num + 1) * sizeof(XpmExtension)" wrapping? */ |
if (!ext) { | if (!ext) { |
XpmFree(string); | XpmFree(string); |
XpmFreeExtensions(exts, num); | XpmFreeExtensions(exts, num); |
|
|
while ((notstart = strncmp("XPMEXT", string, 6)) | while ((notstart = strncmp("XPMEXT", string, 6)) |
&& (notend = strncmp("XPMENDEXT", string, 9))) { | && (notend = strncmp("XPMENDEXT", string, 9))) { |
sp = (char **) | sp = (char **) |
XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); |
XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); /* can we iterate enough for a wrapping? */ |
if (!sp) { | if (!sp) { |
XpmFree(string); | XpmFree(string); |
ext->nlines = nlines; | ext->nlines = nlines; |
|
|
|
/* |
|
* Copyright (C) 2004 The X.Org fundation |
|
* |
|
* Permission is hereby granted, free of charge, to any person |
|
* obtaining a copy of this software and associated documentation |
|
* files (the "Software"), to deal in the Software without |
|
* restriction, including without limitation the rights to use, copy, |
|
* modify, merge, publish, distribute, sublicense, and/or sell copies |
|
* of the Software, and to permit persons to whom the Software is fur- |
|
* nished to do so, subject to the following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be |
|
* included in all copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR |
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
* |
|
* Except as contained in this notice, the name of the X.Org fundation |
|
* shall not be used in advertising or otherwise to promote the sale, |
|
* use or other dealings in this Software without prior written |
|
* authorization from the X.Org fundation. |
|
*/ |
|
|
|
/* |
|
** This is a secure but NOT 100% compatible replacement for popen() |
|
** Note: - don't use pclose() use fclose() for closing the returned |
|
** filedesc.!!! |
|
** |
|
** Known Bugs: - unable to use i/o-redirection like > or < |
|
** Author: - Thomas Biege <thomas@suse.de> |
|
** Credits: - Andreas Pfaller <a.pfaller@pop.gun.de> for fixing a SEGV when |
|
** calling strtok() |
|
*/ |
|
|
|
#include <sys/types.h> |
|
#include <sys/wait.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <string.h> |
|
#include "XpmI.h" |
|
|
|
#define __SEC_POPEN_TOKEN " " |
|
|
|
FILE *s_popen(char *cmd, const char *type) |
|
{ |
|
pid_t pid; |
|
int pfd[2]; |
|
int rpipe = 0, wpipe = 0, i; |
|
char **argv; |
|
char *ptr; |
|
char *cmdcpy; |
|
|
|
|
|
if(cmd == NULL || cmd == "") |
|
return(NULL); |
|
|
|
if(type[0] != 'r' && type[0] != 'w') |
|
return(NULL); |
|
|
|
if ((cmdcpy = strdup(cmd)) == NULL) |
|
return(NULL); |
|
|
|
argv = NULL; |
|
if( (ptr = strtok(cmdcpy, __SEC_POPEN_TOKEN)) == NULL) |
|
{ |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
|
|
for(i = 0;; i++) |
|
{ |
|
if( ( argv = (char **) realloc(argv, (i+1) * sizeof(char *)) ) == NULL) |
|
{ |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
|
|
if( (*(argv+i) = (char *) malloc((strlen(ptr)+1) * sizeof(char))) == NULL) |
|
{ |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
|
|
strcpy(argv[i], ptr); |
|
|
|
if( (ptr = strtok(NULL, __SEC_POPEN_TOKEN)) == NULL) |
|
{ |
|
if( ( argv = (char **) realloc(argv, (i+2) * sizeof(char *))) == NULL) |
|
{ |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
argv[i+1] = NULL; |
|
break; |
|
} |
|
} |
|
|
|
|
|
if(type[0] == 'r') |
|
rpipe = 1; |
|
else |
|
wpipe = 1; |
|
|
|
if (pipe(pfd) < 0) |
|
{ |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
|
|
if((pid = fork()) < 0) |
|
{ |
|
close(pfd[0]); |
|
close(pfd[1]); |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
|
|
if(pid == 0) /* child */ |
|
{ |
|
if((pid = fork()) < 0) |
|
{ |
|
close(pfd[0]); |
|
close(pfd[1]); |
|
free(cmdcpy); |
|
return(NULL); |
|
} |
|
if(pid > 0) |
|
{ |
|
exit(0); /* child nr. 1 exits */ |
|
} |
|
|
|
/* child nr. 2 */ |
|
if(rpipe) |
|
{ |
|
close(pfd[0]); /* close reading end, we don't need it */ |
|
dup2(STDOUT_FILENO, STDERR_FILENO); |
|
if (pfd[1] != STDOUT_FILENO) |
|
dup2(pfd[1], STDOUT_FILENO); /* redirect stdout to writing end of pipe */ |
|
} |
|
else |
|
{ |
|
close(pfd[1]); /* close writing end, we don't need it */ |
|
if (pfd[0] != STDIN_FILENO) |
|
dup2(pfd[0], STDIN_FILENO); /* redirect stdin to reading end of pipe */ |
|
} |
|
|
|
if(strchr(argv[0], '/') == NULL) |
|
execvp(argv[0], argv); /* search in $PATH */ |
|
else |
|
execv(argv[0], argv); |
|
|
|
close(pfd[0]); |
|
close(pfd[1]); |
|
free(cmdcpy); |
|
return(NULL); /* exec failed.. ooops! */ |
|
} |
|
else /* parent */ |
|
{ |
|
waitpid(pid, NULL, 0); /* wait for child nr. 1 */ |
|
|
|
if(rpipe) |
|
{ |
|
close(pfd[1]); |
|
free(cmdcpy); |
|
return(fdopen(pfd[0], "r")); |
|
} |
|
else |
|
{ |
|
close(pfd[0]); |
|
free(cmdcpy); |
|
return(fdopen(pfd[1], "w")); |
|
} |
|
|
|
} |
|
} |
|
|
|
|
* Developed by Arnaud Le Hors * | * Developed by Arnaud Le Hors * |
\*****************************************************************************/ | \*****************************************************************************/ |
| |
|
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ |
|
|
#include "XpmI.h" | #include "XpmI.h" |
#if !defined(NO_ZPIPE) && defined(WIN32) | #if !defined(NO_ZPIPE) && defined(WIN32) |
# define popen _popen | # define popen _popen |
|
|
XpmInfo *info; | XpmInfo *info; |
{ | { |
xpmData mdata; | xpmData mdata; |
char *name, *dot, *s, new_name[BUFSIZ]; |
char *name, *dot, *s, new_name[BUFSIZ] = {0}; |
int ErrorStatus; | int ErrorStatus; |
| |
/* open file to write */ | /* open file to write */ |
|
|
#endif | #endif |
/* let's try to make a valid C syntax name */ | /* let's try to make a valid C syntax name */ |
if (dot = index(name, '.')) { | if (dot = index(name, '.')) { |
strcpy(new_name, name); |
strncpy(new_name, name, sizeof(new_name)); |
|
new_name[sizeof(new_name)-1] = 0; |
/* change '.' to '_' */ | /* change '.' to '_' */ |
name = s = new_name; | name = s = new_name; |
while (dot = index(s, '.')) { | while (dot = index(s, '.')) { |
|
|
} | } |
if (dot = index(name, '-')) { | if (dot = index(name, '-')) { |
if (name != new_name) { | if (name != new_name) { |
strcpy(new_name, name); |
strncpy(new_name, name, sizeof(new_name)); |
|
new_name[sizeof(new_name)-1] = 0; |
name = new_name; | name = new_name; |
} | } |
/* change '-' to '_' */ | /* change '-' to '_' */ |
|
|
unsigned int x, y, h; | unsigned int x, y, h; |
| |
h = height - 1; | h = height - 1; |
if (cpp != 0 && width >= (SIZE_MAX - 3)/cpp) |
if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) |
return XpmNoMemory; | return XpmNoMemory; |
p = buf = (char *) XpmMalloc(width * cpp + 3); | p = buf = (char *) XpmMalloc(width * cpp + 3); |
if (!buf) | if (!buf) |
|
|
/* | /* |
* open the given file to be written as an xpmData which is returned | * open the given file to be written as an xpmData which is returned |
*/ | */ |
|
#ifndef NO_ZPIPE |
|
FILE *s_popen(char *cmd, const char *type); |
|
#else |
|
# define s_popen popen |
|
#endif |
static int | static int |
OpenWriteFile(filename, mdata) | OpenWriteFile(filename, mdata) |
char *filename; | char *filename; |
|
|
mdata->type = XPMFILE; | mdata->type = XPMFILE; |
} else { | } else { |
#ifndef NO_ZPIPE | #ifndef NO_ZPIPE |
int len = strlen(filename); |
size_t len = strlen(filename); |
|
|
|
if(len == 0 || |
|
filename[0] == '/' || |
|
strstr(filename, "../") != NULL || |
|
filename[len-1] == '/') |
|
return(XpmOpenFailed); |
|
|
if (len > 2 && !strcmp(".Z", filename + (len - 2))) { | if (len > 2 && !strcmp(".Z", filename + (len - 2))) { |
sprintf(buf, "compress > \"%s\"", filename); |
snprintf(buf, sizeof(buf), "compress > \"%s\"", filename); |
if (!(mdata->stream.file = popen(buf, "w"))) |
if (!(mdata->stream.file = s_popen(buf, "w"))) |
return (XpmOpenFailed); | return (XpmOpenFailed); |
| |
mdata->type = XPMPIPE; | mdata->type = XPMPIPE; |
} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) { | } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) { |
sprintf(buf, "gzip -q > \"%s\"", filename); |
snprintf(buf, sizeof(buf), "gzip -q > \"%s\"", filename); |
if (!(mdata->stream.file = popen(buf, "w"))) |
if (!(mdata->stream.file = s_popen(buf, "w"))) |
return (XpmOpenFailed); | return (XpmOpenFailed); |
| |
mdata->type = XPMPIPE; | mdata->type = XPMPIPE; |
|
|
break; | break; |
#ifndef NO_ZPIPE | #ifndef NO_ZPIPE |
case XPMPIPE: | case XPMPIPE: |
pclose(mdata->stream.file); |
fclose(mdata->stream.file); |
break; | break; |
#endif | #endif |
} | } |
|
|
unsigned int size = table->size; | unsigned int size = table->size; |
xpmHashAtom *t, *p; | xpmHashAtom *t, *p; |
int i; | int i; |
int oldSize = size; |
unsigned int oldSize = size; |
| |
t = atomTable; | t = atomTable; |
HASH_TABLE_GROWS | HASH_TABLE_GROWS |
table->size = size; | table->size = size; |
table->limit = size / 3; | table->limit = size / 3; |
if (size >= SIZE_MAX / sizeof(*atomTable)) |
if (size >= UINT_MAX / sizeof(*atomTable)) |
return (XpmNoMemory); | return (XpmNoMemory); |
atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable)); | atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable)); |
if (!atomTable) | if (!atomTable) |
|
|
table->size = INITIAL_HASH_SIZE; | table->size = INITIAL_HASH_SIZE; |
table->limit = table->size / 3; | table->limit = table->size / 3; |
table->used = 0; | table->used = 0; |
if (table->size >= SIZE_MAX / sizeof(*atomTable)) |
if (table->size >= UINT_MAX / sizeof(*atomTable)) |
return (XpmNoMemory); | return (XpmNoMemory); |
atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable)); | atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable)); |
if (!atomTable) | if (!atomTable) |