|
|
| |
/* allocate space for the PNG image data */ | /* allocate space for the PNG image data */ |
rowbytes = png_get_rowbytes(png_ptr, info_ptr); | rowbytes = png_get_rowbytes(png_ptr, info_ptr); |
if (overflow2(rowbytes, height)) { |
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
return NULL; |
} |
if ((image_data = (png_bytep)gdMalloc(rowbytes*height)) == NULL) { | if ((image_data = (png_bytep)gdMalloc(rowbytes*height)) == NULL) { |
fprintf(stderr, "gd-png error: cannot allocate image data\n"); | fprintf(stderr, "gd-png error: cannot allocate image data\n"); |
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); |
return NULL; | return NULL; |
} | } |
if (overflow2(height, sizeof (png_bytep))) { |
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
gdFree (image_data); |
return NULL; |
} |
if ((row_pointers = (png_bytepp)gdMalloc(height*sizeof(png_bytep))) == NULL) { | if ((row_pointers = (png_bytepp)gdMalloc(height*sizeof(png_bytep))) == NULL) { |
fprintf(stderr, "gd-png error: cannot allocate row pointers\n"); | fprintf(stderr, "gd-png error: cannot allocate row pointers\n"); |
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); |
|
|
* interlaced images, but interlacing causes some serious complications. */ | * interlaced images, but interlacing causes some serious complications. */ |
if (remap) { | if (remap) { |
png_bytep *row_pointers; | png_bytep *row_pointers; |
if (overflow2(sizeof (png_bytep), height)) { |
return; |
} |
row_pointers = gdMalloc(sizeof(png_bytep) * height); | row_pointers = gdMalloc(sizeof(png_bytep) * height); |
if (row_pointers == NULL) { | if (row_pointers == NULL) { |
fprintf(stderr, "gd-png error: unable to allocate row_pointers\n"); | fprintf(stderr, "gd-png error: unable to allocate row_pointers\n"); |
return; |
} | } |
for (j = 0; j < height; ++j) { | for (j = 0; j < height; ++j) { |
if ((row_pointers[j] = (png_bytep)gdMalloc(width)) == NULL) { | if ((row_pointers[j] = (png_bytep)gdMalloc(width)) == NULL) { |
fprintf(stderr, "gd-png error: unable to allocate rows\n"); | fprintf(stderr, "gd-png error: unable to allocate rows\n"); |
for (i = 0; i < j; ++i) | for (i = 0; i < j; ++i) |
gdFree(row_pointers[i]); | gdFree(row_pointers[i]); |
gdFree(row_pointers); |
return; | return; |
} | } |
for (i = 0; i < width; ++i) | for (i = 0; i < width; ++i) |
|
|
/* |
* gd_security.c |
* |
* Implements buffer overflow check routines. |
* |
* Written 2004, Phil Knirsch. |
* Based on netpbm fixes by Alan Cox. |
* |
*/ |
|
#ifdef HAVE_CONFIG_H |
#include "config.h" |
#endif |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <limits.h> |
#include "gd.h" |
|
int overflow2(int a, int b) |
{ |
if(a < 0 || b < 0) { |
fprintf(stderr, "gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n"); |
return 1; |
} |
if(b == 0) |
return 0; |
if(a > INT_MAX / b) { |
fprintf(stderr, "gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); |
return 1; |
} |
return 0; |
} |
|
|
if ( (wbmp = (Wbmp *) gdMalloc( sizeof(Wbmp) )) == NULL) | if ( (wbmp = (Wbmp *) gdMalloc( sizeof(Wbmp) )) == NULL) |
return (NULL); | return (NULL); |
| |
if (overflow2(sizeof(int), width)) |
{ |
gdFree( wbmp ); |
return (NULL); |
} |
if (overflow2(sizeof(int)*width, height)) |
{ |
gdFree( wbmp ); |
return (NULL); |
} |
if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*width*height )) == NULL) | if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*width*height )) == NULL) |
{ | { |
gdFree( wbmp ); | gdFree( wbmp ); |
|
|
printf("W: %d, H: %d\n", wbmp->width, wbmp->height); | printf("W: %d, H: %d\n", wbmp->width, wbmp->height); |
#endif | #endif |
| |
if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*wbmp->width*wbmp->height )) == NULL) |
if ( overflow2(sizeof (int), wbmp->width) || |
|
overflow2(sizeof (int) * wbmp->width, wbmp->height) || |
|
(wbmp->bitmap = (int *) gdMalloc( sizeof(int)*wbmp->width*wbmp->height )) == NULL) |
{ | { |
gdFree( wbmp ); | gdFree( wbmp ); |
return (-1); | return (-1); |
|
|
int i; | int i; |
gdImagePtr im; | gdImagePtr im; |
im = (gdImage *) gdMalloc(sizeof(gdImage)); | im = (gdImage *) gdMalloc(sizeof(gdImage)); |
if (overflow2(sizeof (unsigned char *), sy)) |
{ |
gdFree(im); |
return NULL; |
} |
/* NOW ROW-MAJOR IN GD 1.3 */ | /* NOW ROW-MAJOR IN GD 1.3 */ |
im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); | im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); |
im->polyInts = 0; | im->polyInts = 0; |
|
|
/* We only need to use floating point to determine the correct | /* We only need to use floating point to determine the correct |
stretch vector for one line's worth. */ | stretch vector for one line's worth. */ |
double accum; | double accum; |
if (overflow2(sizeof (int), srcW) || overflow2(sizeof (int), srcH)) { |
return; |
} |
stx = (int *) gdMalloc(sizeof(int) * srcW); | stx = (int *) gdMalloc(sizeof(int) * srcW); |
sty = (int *) gdMalloc(sizeof(int) * srcH); | sty = (int *) gdMalloc(sizeof(int) * srcH); |
accum = 0; | accum = 0; |
|
|
} | } |
bytes = (w * h / 8) + 1; | bytes = (w * h / 8) + 1; |
im = gdImageCreate(w, h); | im = gdImageCreate(w, h); |
if(!im) { |
return 0; |
} |
gdImageColorAllocate(im, 255, 255, 255); | gdImageColorAllocate(im, 255, 255, 255); |
gdImageColorAllocate(im, 0, 0, 0); | gdImageColorAllocate(im, 0, 0, 0); |
x = 0; | x = 0; |
|
|
return; | return; |
} | } |
if (!im->polyAllocated) { | if (!im->polyAllocated) { |
if (overflow2(sizeof (int), n)) { |
return; |
} |
im->polyInts = (int *) gdMalloc(sizeof(int) * n); | im->polyInts = (int *) gdMalloc(sizeof(int) * n); |
im->polyAllocated = n; | im->polyAllocated = n; |
} | } |
|
|
while (im->polyAllocated < n) { | while (im->polyAllocated < n) { |
im->polyAllocated *= 2; | im->polyAllocated *= 2; |
} | } |
if (overflow2(sizeof (int), im->polyAllocated)) { |
return; |
} |
im->polyInts = (int *) gdRealloc(im->polyInts, | im->polyInts = (int *) gdRealloc(im->polyInts, |
sizeof(int) * im->polyAllocated); | sizeof(int) * im->polyAllocated); |
} | } |
|
|
if (im->style) { | if (im->style) { |
gdFree(im->style); | gdFree(im->style); |
} | } |
if (overflow2(sizeof (int), noOfPixels)) { |
return; |
} |
im->style = (int *) | im->style = (int *) |
gdMalloc(sizeof(int) * noOfPixels); | gdMalloc(sizeof(int) * noOfPixels); |
memcpy(im->style, style, sizeof(int) * noOfPixels); | memcpy(im->style, style, sizeof(int) * noOfPixels); |
|
|
void *gdMalloc(size_t size); | void *gdMalloc(size_t size); |
void *gdRealloc(void *ptr, size_t size); | void *gdRealloc(void *ptr, size_t size); |
| |
/* Returns nonzero if multiplying the two quantities will |
result in integer overflow. Also returns nonzero if |
either quantity is negative. By Phil Knirsch based on |
netpbm fixes by Alan Cox. */ |
|
int overflow2(int a, int b); |
|
#endif /* GDHELPERS_H */ | #endif /* GDHELPERS_H */ |
| |
|
|
| |
bytesNeeded = pos; | bytesNeeded = pos; |
if (bytesNeeded > dp->realSize) { | if (bytesNeeded > dp->realSize) { |
if (overflow2(dp->realSize, 2)) { |
return FALSE; |
} |
if (!gdReallocDynamic(dp,dp->realSize*2)) { | if (!gdReallocDynamic(dp,dp->realSize*2)) { |
dp->dataGood = FALSE; | dp->dataGood = FALSE; |
return FALSE; | return FALSE; |
|
|
bytesNeeded = dp->pos + size; | bytesNeeded = dp->pos + size; |
| |
if (bytesNeeded > dp->realSize) { | if (bytesNeeded > dp->realSize) { |
if (overflow2(bytesNeeded, 2)) { |
return FALSE; |
} |
if (!gdReallocDynamic(dp,bytesNeeded*2)) { | if (!gdReallocDynamic(dp,bytesNeeded*2)) { |
dp->dataGood = FALSE; | dp->dataGood = FALSE; |
return FALSE; | return FALSE; |
|
|
GD2_DBG(printf("Image is %dx%d\n", *sx, *sy)); | GD2_DBG(printf("Image is %dx%d\n", *sx, *sy)); |
| |
im = gdImageCreate(*sx, *sy); | im = gdImageCreate(*sx, *sy); |
|
if (!im) { |
|
goto fail1; |
|
} |
if (!_gdGetColors(in, im)) { | if (!_gdGetColors(in, im)) { |
goto fail2; | goto fail2; |
} | } |
|
|
return 0; | return 0; |
| |
number = image.ncolors; | number = image.ncolors; |
if (overflow2(sizeof (int), number)) { |
return 0; |
} |
colors = (int*)gdMalloc(sizeof(int) * number); | colors = (int*)gdMalloc(sizeof(int) * number); |
if (colors == NULL) | if (colors == NULL) |
return(0); | return(0); |
|
|
fprintf(stderr,"ARRRGH\n"); | fprintf(stderr,"ARRRGH\n"); |
} | } |
| |
apixel = (char *)gdMalloc(image.cpp+1); |
|
if (apixel == NULL) |
|
return(0); |
|
apixel[image.cpp] = '\0'; |
|
|
|
pointer = image.data; | pointer = image.data; |
for(i=0;i<image.height;i++) | for(i=0;i<image.height;i++) |
{ | { |
|
|
gdImageSetPixel(im,j,i,colors[k]); | gdImageSetPixel(im,j,i,colors[k]); |
} | } |
} | } |
gdFree(apixel); |
|
gdFree(colors); | gdFree(colors); |
return(im); | return(im); |
} | } |
|
|
gdtestttf: gdtestttf.o libgd.a | gdtestttf: gdtestttf.o libgd.a |
$(CC) --verbose gdtestttf.o -o gdtestttf $(LIBDIRS) $(LIBS) | $(CC) --verbose gdtestttf.o -o gdtestttf $(LIBDIRS) $(LIBS) |
| |
libgd.a: gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o gd_io_file.o gd_ss.o \ |
libgd.a: gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o gd_io_file.o gd_security.o gd_ss.o \ |
gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o gdfontt.o gdfonts.o gdfontmb.o gdfontl.o \ | gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o gdfontt.o gdfonts.o gdfontmb.o gdfontl.o \ |
gdfontg.o gdtables.o gdft.o gdttf.o gdcache.o gdkanji.o wbmp.o \ | gdfontg.o gdtables.o gdft.o gdttf.o gdcache.o gdkanji.o wbmp.o \ |
gd_wbmp.o gdhelpers.o gd.h gdfontt.h gdfonts.h gdfontmb.h gdfontl.h \ | gd_wbmp.o gdhelpers.o gd.h gdfontt.h gdfonts.h gdfontmb.h gdfontl.h \ |
gdfontg.h gdhelpers.h | gdfontg.h gdhelpers.h |
rm -f libgd.a | rm -f libgd.a |
$(AR) rc libgd.a gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o \ | $(AR) rc libgd.a gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o \ |
gd_io_file.o gd_ss.o gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o \ |
gd_io_file.o gd_security.o gd_ss.o gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o \ |
gdfontt.o gdfonts.o gdfontmb.o gdfontl.o gdfontg.o \ | gdfontt.o gdfonts.o gdfontmb.o gdfontl.o gdfontg.o \ |
gdtables.o gdft.o gdttf.o gdcache.o gdkanji.o wbmp.o \ | gdtables.o gdft.o gdttf.o gdcache.o gdkanji.o wbmp.o \ |
gd_wbmp.o gdhelpers.o | gd_wbmp.o gdhelpers.o |