diff --git a/_imaging.c b/_imaging.c index 68102b611..c6adcde15 100644 --- a/_imaging.c +++ b/_imaging.c @@ -362,9 +362,20 @@ getbands(const char* mode) #define TYPE_DOUBLE (0x400|sizeof(double)) static void* -getlist(PyObject* arg, int* length, const char* wrong_length, int type) +getlist(PyObject* arg, Py_ssize_t* length, const char* wrong_length, int type) { - int i, n, itemp; + /* - allocates and returns a c array of the items in the + python sequence arg. + - the size of the returned array is in length + - all of the arg items must be numeric items of the type + specified in type + - sequence length is checked against the length parameter IF + an error parameter is passed in wrong_length + - caller is responsible for freeing the memory + */ + + Py_ssize_t i, n; + int itemp; double dtemp; void* list; PyObject* seq; @@ -376,12 +387,14 @@ getlist(PyObject* arg, int* length, const char* wrong_length, int type) } n = PyObject_Length(arg); - if (length && wrong_length && n != *length) { + if (length && wrong_length && n != *length) { PyErr_SetString(PyExc_ValueError, wrong_length); return NULL; } - list = malloc(n * (type & 0xff)); + /* malloc check ok, type & ff is just a sizeof(something) + calloc checks for overflow */ + list = calloc(n, type & 0xff); if (!list) return PyErr_NoMemory(); @@ -845,7 +858,7 @@ static PyObject* _filter(ImagingObject* self, PyObject* args) { PyObject* imOut; - int kernelsize; + Py_ssize_t kernelsize; FLOAT32* kerneldata; int xsize, ysize; @@ -859,7 +872,7 @@ _filter(ImagingObject* self, PyObject* args) kerneldata = getlist(kernel, &kernelsize, NULL, TYPE_FLOAT32); if (!kerneldata) return NULL; - if (kernelsize != xsize * ysize) { + if (kernelsize != (Py_ssize_t) xsize * (Py_ssize_t) ysize) { free(kerneldata); return ImagingError_ValueError("bad kernel size"); } @@ -1148,8 +1161,8 @@ _point(ImagingObject* self, PyObject* args) { static const char* wrong_number = "wrong number of lut entries"; - int n, i; - int bands; + Py_ssize_t n; + int i, bands; Imaging im; PyObject* list; @@ -1664,7 +1677,7 @@ _transform2(ImagingObject* self, PyObject* args) Imaging imIn; Imaging imOut; - int n; + Py_ssize_t n; double *a; ImagingObject* imagep; @@ -1920,6 +1933,7 @@ _getprojection(ImagingObject* self, PyObject* args) unsigned char* yprofile; PyObject* result; + /* malloc check ok */ xprofile = malloc(self->image->xsize); yprofile = malloc(self->image->ysize); @@ -2731,7 +2745,7 @@ _draw_polygon(ImagingDrawObject* self, PyObject* args) } /* Copy list of vertices to array */ - ixy = (int*) malloc(n * 2 * sizeof(int)); + ixy = (int*) calloc(n, 2 * sizeof(int)); for (i = 0; i < n; i++) { ixy[i+i] = (int) xy[i+i]; diff --git a/decode.c b/decode.c index 29c0f9a1b..0c66243cd 100644 --- a/decode.c +++ b/decode.c @@ -188,8 +188,13 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args) /* Allocate memory buffer (if bits field is set) */ if (state->bits > 0) { - if (!state->bytes) + if (!state->bytes) { + if (state->xsize > ((SIZE_MAX / state->bits)-7)){ + return PyErr_NoMemory(); + } state->bytes = (state->bits * state->xsize+7)/8; + } + /* malloc check ok, oveflow checked above */ state->buffer = (UINT8*) malloc(state->bytes); if (!state->buffer) return PyErr_NoMemory(); diff --git a/encode.c b/encode.c index 84e5b96b1..d821a54df 100644 --- a/encode.c +++ b/encode.c @@ -159,6 +159,7 @@ _encode_to_file(ImagingEncoderObject* encoder, PyObject* args) return NULL; /* Allocate an encoder buffer */ + /* malloc check ok, either constant int, or checked by PyArg_ParseTuple */ buf = (UINT8*) malloc(bufsize); if (!buf) return PyErr_NoMemory(); @@ -233,7 +234,11 @@ _setimage(ImagingEncoderObject* encoder, PyObject* args) /* Allocate memory buffer (if bits field is set) */ if (state->bits > 0) { + if (state->xsize > ((SIZE_MAX / state->bits)-7)) { + return PyErr_NoMemory(); + } state->bytes = (state->bits * state->xsize+7)/8; + /* malloc check ok, overflow checked above */ state->buffer = (UINT8*) malloc(state->bytes); if (!state->buffer) return PyErr_NoMemory(); @@ -482,6 +487,7 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args) free this memory later, so this function (and several others here) leaks. */ if (dictionary && dictionary_size > 0) { + /* malloc check ok, size comes from PyArg_ParseTuple */ char* p = malloc(dictionary_size); if (!p) return PyErr_NoMemory(); @@ -559,6 +565,7 @@ static unsigned int* get_qtables_arrays(PyObject* qtables, int* qtablesLen) { Py_DECREF(tables); return NULL; } + /* malloc check ok, num_tables <4, DCTSIZE2 == 64 from jpeglib.h */ qarrays = (unsigned int*) malloc(num_tables * DCTSIZE2 * sizeof(unsigned int)); if (!qarrays) { Py_DECREF(tables); @@ -634,6 +641,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args) qarrays = get_qtables_arrays(qtables, &qtablesLen); if (extra && extra_size > 0) { + /* malloc check ok, length is from python parsearg */ char* p = malloc(extra_size); // Freed in JpegEncode, Case 5 if (!p) return PyErr_NoMemory(); @@ -643,6 +651,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args) extra = NULL; if (rawExif && rawExifLen > 0) { + /* malloc check ok, length is from python parsearg */ char* pp = malloc(rawExifLen); // Freed in JpegEncode, Case 5 if (!pp) return PyErr_NoMemory(); @@ -757,15 +766,16 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args) (ttag_t) PyInt_AsLong(key), PyBytes_AsString(value)); } else if (PyTuple_Check(value)) { - int len,i; + Py_ssize_t len,i; float *floatav; int *intav; TRACE(("Setting from Tuple: %d \n", (int)PyInt_AsLong(key))); - len = (int)PyTuple_Size(value); + len = PyTuple_Size(value); if (len) { if (PyInt_Check(PyTuple_GetItem(value,0))) { - TRACE((" %d elements, setting as ints \n", len)); - intav = malloc(sizeof(int)*len); + TRACE((" %d elements, setting as ints \n", (int)len)); + /* malloc check ok, calloc checks for overflow */ + intav = calloc(len, sizeof(int)); if (intav) { for (i=0;iinfo = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); if (!dib->info) { diff --git a/libImaging/Draw.c b/libImaging/Draw.c index 423f1bea2..9bc5800b9 100644 --- a/libImaging/Draw.c +++ b/libImaging/Draw.c @@ -434,7 +434,8 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, } /* Initialize the edge table and find polygon boundaries */ - edge_table = malloc(sizeof(Edge*) * n); + /* malloc check ok, using calloc */ + edge_table = calloc(n, sizeof(Edge*)); if (!edge_table) { return -1; } @@ -462,7 +463,8 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, } /* Process the edge table with a scan line searching for intersections */ - xx = malloc(sizeof(float) * edge_count * 2); + /* malloc check ok, using calloc */ + xx = calloc(edge_count * 2, sizeof(float)); if (!xx) { free(edge_table); return -1; @@ -700,7 +702,8 @@ ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_, if (fill) { /* Build edge list */ - Edge* e = malloc(count * sizeof(Edge)); + /* malloc check ok, using calloc */ + Edge* e = calloc(count, sizeof(Edge)); if (!e) { (void) ImagingError_MemoryError(); return -1; @@ -772,7 +775,8 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1, if (mode != ARC && fill) { /* Build edge list */ - Edge* e = malloc((end - start + 3) * sizeof(Edge)); + /* malloc check UNDONE, FLOAT? */ + Edge* e = calloc((end - start + 3), sizeof(Edge)); if (!e) { ImagingError_MemoryError(); return -1; @@ -930,8 +934,11 @@ allocate(ImagingOutline outline, int extra) /* expand outline buffer */ outline->size += extra + 25; if (!outline->edges) - e = malloc(outline->size * sizeof(Edge)); + /* malloc check ok, uses calloc for overflow */ + e = calloc(outline->size, sizeof(Edge)); else + /* malloc check UNDONE, overflow, realloc to larger, + if it fails, it will leak memory */ e = realloc(outline->edges, outline->size * sizeof(Edge)); if (!e) return NULL; diff --git a/libImaging/Geometry.c b/libImaging/Geometry.c index 97cbcf2ed..df4f79fd7 100644 --- a/libImaging/Geometry.c +++ b/libImaging/Geometry.c @@ -712,8 +712,9 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn, x1 = imOut->xsize; if (y1 > imOut->ysize) y1 = imOut->ysize; - - xintab = (int*) malloc(imOut->xsize * sizeof(int)); + + /* malloc check ok, uses calloc for overflow */ + xintab = (int*) calloc(imOut->xsize, sizeof(int)); if (!xintab) { ImagingDelete(imOut); return (Imaging) ImagingError_MemoryError(); diff --git a/libImaging/GifEncode.c b/libImaging/GifEncode.c index 4ada55496..f211814ed 100644 --- a/libImaging/GifEncode.c +++ b/libImaging/GifEncode.c @@ -61,6 +61,7 @@ emit(GIFENCODERSTATE *context, int byte) block = context->free; context->free = NULL; } else { + /* malloc check ok, small constant allocation */ block = malloc(sizeof(GIFENCODERBLOCK)); if (!block) return 0; diff --git a/libImaging/Incremental.c b/libImaging/Incremental.c index f34765423..68776992a 100644 --- a/libImaging/Incremental.c +++ b/libImaging/Incremental.c @@ -168,6 +168,7 @@ ImagingIncrementalCodecCreate(ImagingIncrementalCodecEntry codec_entry, int seekable, int fd) { + /* malloc check ok, small constant allocation */ ImagingIncrementalCodec codec = (ImagingIncrementalCodec)malloc(sizeof(struct ImagingIncrementalCodecStruct)); codec->entry = codec_entry; diff --git a/libImaging/Palette.c b/libImaging/Palette.c index 93de49f20..31c2c0245 100644 --- a/libImaging/Palette.c +++ b/libImaging/Palette.c @@ -103,7 +103,7 @@ ImagingPaletteDuplicate(ImagingPalette palette) if (!palette) return NULL; - + /* malloc check ok, small constant allocation */ new_palette = malloc(sizeof(struct ImagingPaletteInstance)); if (!new_palette) return (ImagingPalette) ImagingError_MemoryError(); @@ -288,6 +288,7 @@ ImagingPaletteCachePrepare(ImagingPalette palette) /* The cache is 512k. It might be a good idea to break it up into a pointer array (e.g. an 8-bit image?) */ + /* malloc check ok, small constant allocation */ palette->cache = (INT16*) malloc(entries * sizeof(INT16)); if (!palette->cache) { (void) ImagingError_MemoryError(); diff --git a/libImaging/Quant.c b/libImaging/Quant.c index 6c122eee2..e16646b96 100644 --- a/libImaging/Quant.c +++ b/libImaging/Quant.c @@ -150,6 +150,7 @@ create_pixel_hash(Pixel *pixelData,uint32_t nPixels) uint32_t timer,timer2,timer3; #endif + /* malloc check ok, small constant allocation */ d=malloc(sizeof(PixelHashData)); if (!d) return NULL; hash=hashtable_new(pixel_hash,pixel_cmp); @@ -234,6 +235,7 @@ hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void * PIXEL_SCALE(&pixel,&q,d->scale); + /* malloc check ok, small constant allocation */ p=malloc(sizeof(PixelList)); if (!p) return; @@ -557,6 +559,7 @@ split(BoxNode *node) exit(1); } #endif + /* malloc check ok, small constant allocation */ left=malloc(sizeof(BoxNode)); right=malloc(sizeof(BoxNode)); if (!left||!right) { @@ -613,6 +616,7 @@ median_cut(PixelList *hl[3], BoxNode *thisNode; h=ImagingQuantHeapNew(box_heap_cmp); + /* malloc check ok, small constant allocation */ root=malloc(sizeof(BoxNode)); if (!root) { ImagingQuantHeapFree(h); return NULL; } for(i=0;i<3;i++) { @@ -954,15 +958,16 @@ compute_palette_from_median_cut( uint32_t *count; *palette=NULL; - if (!(count=malloc(sizeof(uint32_t)*nPaletteEntries))) { + /* malloc check ok, using calloc */ + if (!(count=calloc(nPaletteEntries, sizeof(uint32_t)))) { return 0; } - memset(count,0,sizeof(uint32_t)*nPaletteEntries); for(i=0;i<3;i++) { avg[i]=NULL; } for(i=0;i<3;i++) { - if (!(avg[i]=malloc(sizeof(uint32_t)*nPaletteEntries))) { + /* malloc check ok, using calloc */ + if (!(avg[i]=calloc(nPaletteEntries, sizeof(uint32_t)))) { for(i=0;i<3;i++) { if (avg[i]) free (avg[i]); } @@ -970,9 +975,6 @@ compute_palette_from_median_cut( return 0; } } - for(i=0;i<3;i++) { - memset(avg[i],0,sizeof(uint32_t)*nPaletteEntries); - } for (i=0;i SIZE_MAX / (nPaletteEntries * sizeof(uint32_t))) { + goto error_1; + } + /* malloc check ok, using calloc, checking n*n above */ + avgDist=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t)); if (!avgDist) { goto error_1; } - avgDistSortKey=malloc(sizeof(uint32_t *)*nPaletteEntries*nPaletteEntries); + /* malloc check ok, using calloc, checking n*n above */ + avgDistSortKey=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t *)); if (!avgDistSortKey) { goto error_2; } #ifndef NO_OUTPUT @@ -1251,13 +1262,20 @@ quantize(Pixel *pixelData, free_box_tree(root); root=NULL; - qp=malloc(sizeof(uint32_t)*nPixels); + /* malloc check ok, using calloc for overflow */ + qp=calloc(nPixels, sizeof(uint32_t)); if (!qp) { goto error_4; } - avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries); + if ((nPaletteEntries > SIZE_MAX / nPaletteEntries ) || + (nPaletteEntries > SIZE_MAX / (nPaletteEntries * sizeof(uint32_t)))) { + goto error_5; + } + /* malloc check ok, using calloc for overflow, check of n*n above */ + avgDist=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t)); if (!avgDist) { goto error_5; } - avgDistSortKey=malloc(sizeof(uint32_t *)*nPaletteEntries*nPaletteEntries); + /* malloc check ok, using calloc for overflow, check of n*n above */ + avgDistSortKey=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t *)); if (!avgDistSortKey) { goto error_6; } if (!build_distance_tables(avgDist,avgDistSortKey,p,nPaletteEntries)) { @@ -1399,8 +1417,9 @@ quantize2(Pixel *pixelData, uint32_t *qp; uint32_t *avgDist; uint32_t **avgDistSortKey; - - p=malloc(sizeof(Pixel)*nQuantPixels); + + /* malloc check ok, using calloc */ + p=calloc(nQuantPixels, sizeof(Pixel)); if (!p) return 0; mean[0]=mean[1]=mean[2]=0; h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); @@ -1422,13 +1441,21 @@ quantize2(Pixel *pixelData, } hashtable_free(h); - qp=malloc(sizeof(uint32_t)*nPixels); + /* malloc check ok, using calloc */ + qp=calloc(nPixels, sizeof(uint32_t)); if (!qp) { goto error_1; } - avgDist=malloc(sizeof(uint32_t)*nQuantPixels*nQuantPixels); + if ((nQuantPixels > SIZE_MAX / nQuantPixels ) || + (nQuantPixels > SIZE_MAX / (nQuantPixels * sizeof(uint32_t)))) { + goto error_2; + } + + /* malloc check ok, using calloc for overflow, check of n*n above */ + avgDist=calloc(nQuantPixels*nQuantPixels, sizeof(uint32_t)); if (!avgDist) { goto error_2; } - avgDistSortKey=malloc(sizeof(uint32_t *)*nQuantPixels*nQuantPixels); + /* malloc check ok, using calloc for overflow, check of n*n above */ + avgDistSortKey=calloc(nQuantPixels*nQuantPixels, sizeof(uint32_t *)); if (!avgDistSortKey) { goto error_3; } if (!build_distance_tables(avgDist,avgDistSortKey,p,nQuantPixels)) { @@ -1474,7 +1501,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) ImagingSectionCookie cookie; if (!im) - return ImagingError_ModeError(); + return ImagingError_ModeError(); if (colors < 1 || colors > 256) /* FIXME: for colors > 256, consider returning an RGB image instead (see @PIL205) */ @@ -1488,7 +1515,12 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) if (!strcmp(im->mode, "RGBA") && mode != 2 && mode != 3) return ImagingError_ModeError(); - p = malloc(sizeof(Pixel) * im->xsize * im->ysize); + if ((im->xsize > SIZE_MAX / im->ysize) || + (im->xsize > SIZE_MAX / (im->ysize * sizeof(Pixel)))) { + return ImagingError_MemoryError(); + } + /* malloc check ok, using calloc for final overflow, x*y above */ + p = calloc(im->xsize * im->ysize, sizeof(Pixel)); if (!p) return ImagingError_MemoryError(); diff --git a/libImaging/QuantHeap.c b/libImaging/QuantHeap.c index 9006903b7..2edf6d9cf 100644 --- a/libImaging/QuantHeap.c +++ b/libImaging/QuantHeap.c @@ -47,7 +47,12 @@ static int _heap_grow(Heap *h,int newsize) { void *newheap; if (!newsize) newsize=h->heapsize<<1; if (newsizeheapsize) return 0; - newheap=malloc(sizeof(void *)*newsize); + if (newsize > ((int)SIZE_MAX) / sizeof(void *)){ + return 0; + } + /* malloc check ok, using calloc for overflow, also checking + above due to memcpy below*/ + newheap=calloc(newsize, sizeof(void *)); if (!newheap) return 0; memcpy(newheap,h->heap,sizeof(void *)*h->heapsize); free(h->heap); @@ -131,12 +136,17 @@ int ImagingQuantHeapTop(Heap *h,void **r) { Heap *ImagingQuantHeapNew(HeapCmpFunc cf) { Heap *h; - + + /* malloc check ok, small constant allocation */ h=malloc(sizeof(Heap)); if (!h) return NULL; h->heapsize=INITIAL_SIZE; - h->heap=malloc(sizeof(void *)*h->heapsize); - if (!h->heap) { free(h); return NULL; } + /* malloc check ok, using calloc for overflow */ + h->heap=calloc(h->heapsize, sizeof(void *)); + if (!h->heap) { + free(h); + return NULL; + } h->heapcount=0; h->cf=cf; return h; diff --git a/libImaging/QuantOctree.c b/libImaging/QuantOctree.c index cd0d7fbd1..3f61f0722 100644 --- a/libImaging/QuantOctree.c +++ b/libImaging/QuantOctree.c @@ -53,6 +53,7 @@ static ColorCube new_color_cube(int r, int g, int b, int a) { ColorCube cube; + /* malloc check ok, small constant allocation */ cube = malloc(sizeof(struct _ColorCube)); if (!cube) return NULL; @@ -154,7 +155,11 @@ compare_bucket_count(const ColorBucket a, const ColorBucket b) { static ColorBucket create_sorted_color_palette(const ColorCube cube) { ColorBucket buckets; - buckets = malloc(sizeof(struct _ColorBucket)*cube->size); + if (cube->size > SIZE_MAX / sizeof(struct _ColorBucket)) { + return NULL; + } + /* malloc check ok, calloc + overflow check above for memcpy */ + buckets = calloc(cube->size, sizeof(struct _ColorBucket)); if (!buckets) return NULL; memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket)*cube->size); @@ -280,7 +285,15 @@ void add_lookup_buckets(ColorCube cube, ColorBucket palette, long nColors, long ColorBucket combined_palette(ColorBucket bucketsA, long nBucketsA, ColorBucket bucketsB, long nBucketsB) { ColorBucket result; - result = malloc(sizeof(struct _ColorBucket)*(nBucketsA+nBucketsB)); + if (nBucketsA > SIZE_MAX - nBucketsB || + (nBucketsA+nBucketsB) > SIZE_MAX / sizeof(struct _ColorBucket)) { + return NULL; + } + /* malloc check ok, overflow check above */ + result = calloc(nBucketsA + nBucketsB, sizeof(struct _ColorBucket)); + if (!result) { + return NULL; + } memcpy(result, bucketsA, sizeof(struct _ColorBucket) * nBucketsA); memcpy(&result[nBucketsA], bucketsB, sizeof(struct _ColorBucket) * nBucketsB); return result; @@ -290,8 +303,9 @@ static Pixel * create_palette_array(const ColorBucket palette, unsigned int paletteLength) { Pixel *paletteArray; unsigned int i; - - paletteArray = malloc(sizeof(Pixel)*paletteLength); + + /* malloc check ok, calloc for overflow */ + paletteArray = calloc(paletteLength, sizeof(Pixel)); if (!paletteArray) return NULL; for (i=0; i SIZE_MAX / size || + size > SIZE_MAX / (size * sizeof(FLOAT32))) { + return (Imaging) ImagingError_ValueError("filter size too large"); + } size2 = size * size; margin = (size-1) / 2; diff --git a/libImaging/Storage.c b/libImaging/Storage.c index 4450d14e4..5968ad7a1 100644 --- a/libImaging/Storage.c +++ b/libImaging/Storage.c @@ -306,6 +306,7 @@ ImagingNewArray(const char *mode, int xsize, int ysize) /* Allocate image as an array of lines */ for (y = 0; y < im->ysize; y++) { + /* malloc check UNDONE - where is linesize set? */ p = (char *) malloc(im->linesize); if (!p) { ImagingDestroyArray(im); @@ -345,18 +346,23 @@ ImagingNewBlock(const char *mode, int xsize, int ysize) if (!im) return NULL; - /* Use a single block */ - bytes = (Py_ssize_t) im->ysize * im->linesize; + + if (im->linesize && + im->ysize > SIZE_MAX / im->linesize) { + /* punt if we're going to overflow */ + return NULL; + } + /* Use a single block */ + bytes = ((Py_ssize_t) im->ysize) * im->linesize; if (bytes <= 0) /* some platforms return NULL for malloc(0); this fix prevents MemoryError on zero-sized images on such platforms */ bytes = 1; - im->block = (char *) malloc(bytes); + /* malloc check ok, overflow check above */ + im->block = (char *) calloc(bytes, 1); if (im->block) { - memset(im->block, 0, bytes); - for (y = i = 0; y < im->ysize; y++) { im->image[y] = im->block + i; i += im->linesize; @@ -392,7 +398,7 @@ ImagingNew(const char* mode, int xsize, int ysize) } else bytes = strlen(mode); /* close enough */ - if ((int64_t) xsize * (int64_t) ysize * bytes <= THRESHOLD) { + if ((int64_t) xsize * (int64_t) ysize <= THRESHOLD / bytes) { im = ImagingNewBlock(mode, xsize, ysize); if (im) return im; diff --git a/libImaging/TiffDecode.c b/libImaging/TiffDecode.c index b9b61e48f..3df48c7ba 100644 --- a/libImaging/TiffDecode.c +++ b/libImaging/TiffDecode.c @@ -305,6 +305,7 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) { } else { // malloc a buffer to write the tif, we're going to need to realloc or something if we need bigger. TRACE(("Opening a buffer for writing \n")); + /* malloc check ok, small constant allocation */ clientstate->data = malloc(bufsize); clientstate->size = bufsize; clientstate->flrealloc=1; diff --git a/libImaging/ZipDecode.c b/libImaging/ZipDecode.c index 96c8b21bd..dfcfa36bb 100644 --- a/libImaging/ZipDecode.c +++ b/libImaging/ZipDecode.c @@ -56,9 +56,15 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) context->prefix = 1; /* PNG */ + /* overflow check for malloc */ + if (state->bytes > SIZE_MAX - 1) { + state->errcode = IMAGING_CODEC_MEMORY; + return -1; + } /* Expand standard buffer to make room for the (optional) filter prefix, and allocate a buffer to hold the previous line */ free(state->buffer); + /* malloc check ok, overflow checked above */ state->buffer = (UINT8*) malloc(state->bytes+1); context->previous = (UINT8*) malloc(state->bytes+1); if (!state->buffer || !context->previous) { diff --git a/libImaging/ZipEncode.c b/libImaging/ZipEncode.c index 1e96aee71..7f50be9ed 100644 --- a/libImaging/ZipEncode.c +++ b/libImaging/ZipEncode.c @@ -37,9 +37,16 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) /* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */ + /* overflow check for malloc */ + if (state->bytes > SIZE_MAX - 1) { + state->errcode = IMAGING_CODEC_MEMORY; + return -1; + } + /* Expand standard buffer to make room for the filter selector, and allocate filter buffers */ free(state->buffer); + /* malloc check ok, overflow checked above */ state->buffer = (UINT8*) malloc(state->bytes+1); context->previous = (UINT8*) malloc(state->bytes+1); context->prior = (UINT8*) malloc(state->bytes+1);