Merge pull request #1781 from wiredfool/malloc_check

Integer overflow checks on malloc
This commit is contained in:
wiredfool 2016-06-21 12:09:19 +01:00 committed by GitHub
commit bdd0a6a4e4
21 changed files with 985 additions and 793 deletions

View File

@ -362,9 +362,20 @@ getbands(const char* mode)
#define TYPE_DOUBLE (0x400|sizeof(double)) #define TYPE_DOUBLE (0x400|sizeof(double))
static void* 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; double dtemp;
void* list; void* list;
PyObject* seq; PyObject* seq;
@ -381,7 +392,9 @@ getlist(PyObject* arg, int* length, const char* wrong_length, int type)
return NULL; 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) if (!list)
return PyErr_NoMemory(); return PyErr_NoMemory();
@ -845,7 +858,7 @@ static PyObject*
_filter(ImagingObject* self, PyObject* args) _filter(ImagingObject* self, PyObject* args)
{ {
PyObject* imOut; PyObject* imOut;
int kernelsize; Py_ssize_t kernelsize;
FLOAT32* kerneldata; FLOAT32* kerneldata;
int xsize, ysize; int xsize, ysize;
@ -859,7 +872,7 @@ _filter(ImagingObject* self, PyObject* args)
kerneldata = getlist(kernel, &kernelsize, NULL, TYPE_FLOAT32); kerneldata = getlist(kernel, &kernelsize, NULL, TYPE_FLOAT32);
if (!kerneldata) if (!kerneldata)
return NULL; return NULL;
if (kernelsize != xsize * ysize) { if (kernelsize != (Py_ssize_t) xsize * (Py_ssize_t) ysize) {
free(kerneldata); free(kerneldata);
return ImagingError_ValueError("bad kernel size"); 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"; static const char* wrong_number = "wrong number of lut entries";
int n, i; Py_ssize_t n;
int bands; int i, bands;
Imaging im; Imaging im;
PyObject* list; PyObject* list;
@ -1614,7 +1627,7 @@ _transform2(ImagingObject* self, PyObject* args)
static const char* wrong_number = "wrong number of matrix entries"; static const char* wrong_number = "wrong number of matrix entries";
Imaging imOut; Imaging imOut;
int n; Py_ssize_t n;
double *a; double *a;
ImagingObject* imagep; ImagingObject* imagep;
@ -1849,6 +1862,7 @@ _getprojection(ImagingObject* self, PyObject* args)
unsigned char* yprofile; unsigned char* yprofile;
PyObject* result; PyObject* result;
/* malloc check ok */
xprofile = malloc(self->image->xsize); xprofile = malloc(self->image->xsize);
yprofile = malloc(self->image->ysize); yprofile = malloc(self->image->ysize);
@ -2295,7 +2309,7 @@ _draw_dealloc(ImagingDrawObject* self)
PyObject_Del(self); PyObject_Del(self);
} }
extern int PyPath_Flatten(PyObject* data, double **xy); extern Py_ssize_t PyPath_Flatten(PyObject* data, double **xy);
static PyObject* static PyObject*
_draw_ink(ImagingDrawObject* self, PyObject* args) _draw_ink(ImagingDrawObject* self, PyObject* args)
@ -2316,7 +2330,7 @@ static PyObject*
_draw_arc(ImagingDrawObject* self, PyObject* args) _draw_arc(ImagingDrawObject* self, PyObject* args)
{ {
double* xy; double* xy;
int n; Py_ssize_t n;
PyObject* data; PyObject* data;
int ink; int ink;
@ -2352,7 +2366,7 @@ static PyObject*
_draw_bitmap(ImagingDrawObject* self, PyObject* args) _draw_bitmap(ImagingDrawObject* self, PyObject* args)
{ {
double *xy; double *xy;
int n; Py_ssize_t n;
PyObject *data; PyObject *data;
ImagingObject* bitmap; ImagingObject* bitmap;
@ -2388,7 +2402,7 @@ static PyObject*
_draw_chord(ImagingDrawObject* self, PyObject* args) _draw_chord(ImagingDrawObject* self, PyObject* args)
{ {
double* xy; double* xy;
int n; Py_ssize_t n;
PyObject* data; PyObject* data;
int ink, fill; int ink, fill;
@ -2424,7 +2438,7 @@ static PyObject*
_draw_ellipse(ImagingDrawObject* self, PyObject* args) _draw_ellipse(ImagingDrawObject* self, PyObject* args)
{ {
double* xy; double* xy;
int n; Py_ssize_t n;
PyObject* data; PyObject* data;
int ink; int ink;
@ -2475,7 +2489,7 @@ static PyObject*
_draw_lines(ImagingDrawObject* self, PyObject* args) _draw_lines(ImagingDrawObject* self, PyObject* args)
{ {
double *xy; double *xy;
int i, n; Py_ssize_t i, n;
PyObject *data; PyObject *data;
int ink; int ink;
@ -2543,7 +2557,7 @@ static PyObject*
_draw_points(ImagingDrawObject* self, PyObject* args) _draw_points(ImagingDrawObject* self, PyObject* args)
{ {
double *xy; double *xy;
int i, n; Py_ssize_t i, n;
PyObject *data; PyObject *data;
int ink; int ink;
@ -2605,7 +2619,7 @@ static PyObject*
_draw_pieslice(ImagingDrawObject* self, PyObject* args) _draw_pieslice(ImagingDrawObject* self, PyObject* args)
{ {
double* xy; double* xy;
int n; Py_ssize_t n;
PyObject* data; PyObject* data;
int ink, fill; int ink, fill;
@ -2641,7 +2655,7 @@ _draw_polygon(ImagingDrawObject* self, PyObject* args)
{ {
double *xy; double *xy;
int *ixy; int *ixy;
int n, i; Py_ssize_t n, i;
PyObject* data; PyObject* data;
int ink; int ink;
@ -2660,7 +2674,7 @@ _draw_polygon(ImagingDrawObject* self, PyObject* args)
} }
/* Copy list of vertices to array */ /* 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++) { for (i = 0; i < n; i++) {
ixy[i+i] = (int) xy[i+i]; ixy[i+i] = (int) xy[i+i];
@ -2685,7 +2699,7 @@ static PyObject*
_draw_rectangle(ImagingDrawObject* self, PyObject* args) _draw_rectangle(ImagingDrawObject* self, PyObject* args)
{ {
double* xy; double* xy;
int n; Py_ssize_t n;
PyObject* data; PyObject* data;
int ink; int ink;

View File

@ -188,8 +188,13 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args)
/* Allocate memory buffer (if bits field is set) */ /* Allocate memory buffer (if bits field is set) */
if (state->bits > 0) { if (state->bits > 0) {
if (!state->bytes) if (!state->bytes) {
if (state->xsize > ((INT_MAX / state->bits)-7)){
return PyErr_NoMemory();
}
state->bytes = (state->bits * state->xsize+7)/8; state->bytes = (state->bits * state->xsize+7)/8;
}
/* malloc check ok, oveflow checked above */
state->buffer = (UINT8*) malloc(state->bytes); state->buffer = (UINT8*) malloc(state->bytes);
if (!state->buffer) if (!state->buffer)
return PyErr_NoMemory(); return PyErr_NoMemory();

View File

@ -159,6 +159,7 @@ _encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
return NULL; return NULL;
/* Allocate an encoder buffer */ /* Allocate an encoder buffer */
/* malloc check ok, either constant int, or checked by PyArg_ParseTuple */
buf = (UINT8*) malloc(bufsize); buf = (UINT8*) malloc(bufsize);
if (!buf) if (!buf)
return PyErr_NoMemory(); return PyErr_NoMemory();
@ -233,7 +234,11 @@ _setimage(ImagingEncoderObject* encoder, PyObject* args)
/* Allocate memory buffer (if bits field is set) */ /* Allocate memory buffer (if bits field is set) */
if (state->bits > 0) { if (state->bits > 0) {
if (state->xsize > ((INT_MAX / state->bits)-7)) {
return PyErr_NoMemory();
}
state->bytes = (state->bits * state->xsize+7)/8; state->bytes = (state->bits * state->xsize+7)/8;
/* malloc check ok, overflow checked above */
state->buffer = (UINT8*) malloc(state->bytes); state->buffer = (UINT8*) malloc(state->bytes);
if (!state->buffer) if (!state->buffer)
return PyErr_NoMemory(); return PyErr_NoMemory();
@ -478,10 +483,9 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
&dictionary, &dictionary_size)) &dictionary, &dictionary_size))
return NULL; return NULL;
/* Copy to avoid referencing Python's memory, but there's no mechanism to /* Copy to avoid referencing Python's memory */
free this memory later, so this function (and several others here)
leaks. */
if (dictionary && dictionary_size > 0) { if (dictionary && dictionary_size > 0) {
/* malloc check ok, size comes from PyArg_ParseTuple */
char* p = malloc(dictionary_size); char* p = malloc(dictionary_size);
if (!p) if (!p)
return PyErr_NoMemory(); return PyErr_NoMemory();
@ -498,6 +502,7 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
return NULL; return NULL;
encoder->encode = ImagingZipEncode; encoder->encode = ImagingZipEncode;
encoder->cleanup = ImagingZipEncodeCleanup;
if (rawmode[0] == 'P') if (rawmode[0] == 'P')
/* disable filtering */ /* disable filtering */
@ -559,6 +564,7 @@ static unsigned int* get_qtables_arrays(PyObject* qtables, int* qtablesLen) {
Py_DECREF(tables); Py_DECREF(tables);
return NULL; return NULL;
} }
/* malloc check ok, num_tables <4, DCTSIZE2 == 64 from jpeglib.h */
qarrays = (unsigned int*) malloc(num_tables * DCTSIZE2 * sizeof(unsigned int)); qarrays = (unsigned int*) malloc(num_tables * DCTSIZE2 * sizeof(unsigned int));
if (!qarrays) { if (!qarrays) {
Py_DECREF(tables); Py_DECREF(tables);
@ -631,9 +637,11 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
if (get_packer(encoder, mode, rawmode) < 0) if (get_packer(encoder, mode, rawmode) < 0)
return NULL; return NULL;
// Freed in JpegEncode, Case 5
qarrays = get_qtables_arrays(qtables, &qtablesLen); qarrays = get_qtables_arrays(qtables, &qtablesLen);
if (extra && extra_size > 0) { if (extra && extra_size > 0) {
/* malloc check ok, length is from python parsearg */
char* p = malloc(extra_size); // Freed in JpegEncode, Case 5 char* p = malloc(extra_size); // Freed in JpegEncode, Case 5
if (!p) if (!p)
return PyErr_NoMemory(); return PyErr_NoMemory();
@ -643,6 +651,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
extra = NULL; extra = NULL;
if (rawExif && rawExifLen > 0) { if (rawExif && rawExifLen > 0) {
/* malloc check ok, length is from python parsearg */
char* pp = malloc(rawExifLen); // Freed in JpegEncode, Case 5 char* pp = malloc(rawExifLen); // Freed in JpegEncode, Case 5
if (!pp) if (!pp)
return PyErr_NoMemory(); return PyErr_NoMemory();
@ -757,15 +766,16 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
(ttag_t) PyInt_AsLong(key), (ttag_t) PyInt_AsLong(key),
PyBytes_AsString(value)); PyBytes_AsString(value));
} else if (PyTuple_Check(value)) { } else if (PyTuple_Check(value)) {
int len,i; Py_ssize_t len,i;
float *floatav; float *floatav;
int *intav; int *intav;
TRACE(("Setting from Tuple: %d \n", (int)PyInt_AsLong(key))); TRACE(("Setting from Tuple: %d \n", (int)PyInt_AsLong(key)));
len = (int)PyTuple_Size(value); len = PyTuple_Size(value);
if (len) { if (len) {
if (PyInt_Check(PyTuple_GetItem(value,0))) { if (PyInt_Check(PyTuple_GetItem(value,0))) {
TRACE((" %d elements, setting as ints \n", len)); TRACE((" %d elements, setting as ints \n", (int)len));
intav = malloc(sizeof(int)*len); /* malloc check ok, calloc checks for overflow */
intav = calloc(len, sizeof(int));
if (intav) { if (intav) {
for (i=0;i<len;i++) { for (i=0;i<len;i++) {
intav[i] = (int)PyInt_AsLong(PyTuple_GetItem(value,i)); intav[i] = (int)PyInt_AsLong(PyTuple_GetItem(value,i));
@ -776,8 +786,9 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
free(intav); free(intav);
} }
} else if (PyFloat_Check(PyTuple_GetItem(value,0))) { } else if (PyFloat_Check(PyTuple_GetItem(value,0))) {
TRACE((" %d elements, setting as floats \n", len)); TRACE((" %d elements, setting as floats \n", (int)len));
floatav = malloc(sizeof(float)*len); /* malloc check ok, calloc checks for overflow */
floatav = calloc(len, sizeof(float));
if (floatav) { if (floatav) {
for (i=0;i<len;i++) { for (i=0;i<len;i++) {
floatav[i] = (float)PyFloat_AsDouble(PyTuple_GetItem(value,i)); floatav[i] = (float)PyFloat_AsDouble(PyTuple_GetItem(value,i));

View File

@ -70,9 +70,11 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
return (ImagingDIB) ImagingError_ModeError(); return (ImagingDIB) ImagingError_ModeError();
/* Create DIB context and info header */ /* Create DIB context and info header */
/* malloc check ok, small constant allocation */
dib = (ImagingDIB) malloc(sizeof(*dib)); dib = (ImagingDIB) malloc(sizeof(*dib));
if (!dib) if (!dib)
return (ImagingDIB) ImagingError_MemoryError(); return (ImagingDIB) ImagingError_MemoryError();
/* malloc check ok, small constant allocation */
dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)); 256 * sizeof(RGBQUAD));
if (!dib->info) { if (!dib->info) {

View File

@ -434,7 +434,8 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill,
} }
/* Initialize the edge table and find polygon boundaries */ /* 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) { if (!edge_table) {
return -1; 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 */ /* 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) { if (!xx) {
free(edge_table); free(edge_table);
return -1; return -1;
@ -700,7 +702,8 @@ ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_,
if (fill) { if (fill) {
/* Build edge list */ /* Build edge list */
Edge* e = malloc(count * sizeof(Edge)); /* malloc check ok, using calloc */
Edge* e = calloc(count, sizeof(Edge));
if (!e) { if (!e) {
(void) ImagingError_MemoryError(); (void) ImagingError_MemoryError();
return -1; return -1;
@ -769,10 +772,16 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
while (end < start) while (end < start)
end += 360; end += 360;
if (end - start > 360) {
/* no need to go in loops */
end = start + 361;
}
if (mode != ARC && fill) { if (mode != ARC && fill) {
/* Build edge list */ /* 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) { if (!e) {
ImagingError_MemoryError(); ImagingError_MemoryError();
return -1; return -1;
@ -929,10 +938,16 @@ allocate(ImagingOutline outline, int extra)
if (outline->count + extra > outline->size) { if (outline->count + extra > outline->size) {
/* expand outline buffer */ /* expand outline buffer */
outline->size += extra + 25; outline->size += extra + 25;
if (!outline->edges) if (!outline->edges) {
e = malloc(outline->size * sizeof(Edge)); /* malloc check ok, uses calloc for overflow */
else e = calloc(outline->size, sizeof(Edge));
} else {
if (outline->size > INT_MAX / sizeof(Edge)) {
return NULL;
}
/* malloc check ok, overflow checked above */
e = realloc(outline->edges, outline->size * sizeof(Edge)); e = realloc(outline->edges, outline->size * sizeof(Edge));
}
if (!e) if (!e)
return NULL; return NULL;
outline->edges = e; outline->edges = e;

View File

@ -684,7 +684,8 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
if (y1 > imOut->ysize) if (y1 > imOut->ysize)
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) { if (!xintab) {
ImagingDelete(imOut); ImagingDelete(imOut);
return (Imaging) ImagingError_MemoryError(); return (Imaging) ImagingError_MemoryError();

View File

@ -61,6 +61,7 @@ emit(GIFENCODERSTATE *context, int byte)
block = context->free; block = context->free;
context->free = NULL; context->free = NULL;
} else { } else {
/* malloc check ok, small constant allocation */
block = malloc(sizeof(GIFENCODERBLOCK)); block = malloc(sizeof(GIFENCODERBLOCK));
if (!block) if (!block)
return 0; return 0;

View File

@ -168,9 +168,9 @@ extern Imaging ImagingNewMap(const char* filename, int readonly,
const char* mode, int xsize, int ysize); const char* mode, int xsize, int ysize);
extern Imaging ImagingNewPrologue(const char *mode, extern Imaging ImagingNewPrologue(const char *mode,
unsigned xsize, unsigned ysize); int xsize, int ysize);
extern Imaging ImagingNewPrologueSubtype(const char *mode, extern Imaging ImagingNewPrologueSubtype(const char *mode,
unsigned xsize, unsigned ysize, int xsize, int ysize,
int structure_size); int structure_size);
extern Imaging ImagingNewEpilogue(Imaging im); extern Imaging ImagingNewEpilogue(Imaging im);
@ -453,6 +453,7 @@ extern int ImagingZipDecode(Imaging im, ImagingCodecState state,
UINT8* buffer, int bytes); UINT8* buffer, int bytes);
extern int ImagingZipEncode(Imaging im, ImagingCodecState state, extern int ImagingZipEncode(Imaging im, ImagingCodecState state,
UINT8* buffer, int bytes); UINT8* buffer, int bytes);
extern int ImagingZipEncodeCleanup(ImagingCodecState state);
#endif #endif
typedef void (*ImagingShuffler)(UINT8* out, const UINT8* in, int pixels); typedef void (*ImagingShuffler)(UINT8* out, const UINT8* in, int pixels);

View File

@ -168,6 +168,7 @@ ImagingIncrementalCodecCreate(ImagingIncrementalCodecEntry codec_entry,
int seekable, int seekable,
int fd) int fd)
{ {
/* malloc check ok, small constant allocation */
ImagingIncrementalCodec codec = (ImagingIncrementalCodec)malloc(sizeof(struct ImagingIncrementalCodecStruct)); ImagingIncrementalCodec codec = (ImagingIncrementalCodec)malloc(sizeof(struct ImagingIncrementalCodecStruct));
codec->entry = codec_entry; codec->entry = codec_entry;
@ -370,7 +371,17 @@ ImagingIncrementalCodecPushBuffer(ImagingIncrementalCodec codec,
/* In this specific case, we append to a buffer we allocate ourselves */ /* In this specific case, we append to a buffer we allocate ourselves */
size_t old_size = codec->stream.end - codec->stream.buffer; size_t old_size = codec->stream.end - codec->stream.buffer;
size_t new_size = codec->stream.end - codec->stream.buffer + bytes; size_t new_size = codec->stream.end - codec->stream.buffer + bytes;
UINT8 *new = (UINT8 *)realloc (codec->stream.buffer, new_size); UINT8 *new;
if (old_size > SIZE_MAX - bytes) {
codec->state->errcode = IMAGING_CODEC_MEMORY;
#ifndef _WIN32
pthread_mutex_unlock(&codec->data_mutex);
#endif
return -1;
}
/* malloc check ok, overflow checked */
new = (UINT8 *)realloc (codec->stream.buffer, new_size);
if (!new) { if (!new) {
codec->state->errcode = IMAGING_CODEC_MEMORY; codec->state->errcode = IMAGING_CODEC_MEMORY;

View File

@ -702,6 +702,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state,
tile_info.y1 = (tile_info.y1 + correction) >> context->reduce; tile_info.y1 = (tile_info.y1 + correction) >> context->reduce;
if (buffer_size < tile_info.data_size) { if (buffer_size < tile_info.data_size) {
/* malloc check ok, tile_info.data_size from openjpeg */
UINT8 *new = realloc (state->buffer, tile_info.data_size); UINT8 *new = realloc (state->buffer, tile_info.data_size);
if (!new) { if (!new) {
state->errcode = IMAGING_CODEC_MEMORY; state->errcode = IMAGING_CODEC_MEMORY;

View File

@ -103,7 +103,7 @@ ImagingPaletteDuplicate(ImagingPalette palette)
if (!palette) if (!palette)
return NULL; return NULL;
/* malloc check ok, small constant allocation */
new_palette = malloc(sizeof(struct ImagingPaletteInstance)); new_palette = malloc(sizeof(struct ImagingPaletteInstance));
if (!new_palette) if (!new_palette)
return (ImagingPalette) ImagingError_MemoryError(); return (ImagingPalette) ImagingError_MemoryError();
@ -288,6 +288,7 @@ ImagingPaletteCachePrepare(ImagingPalette palette)
/* The cache is 512k. It might be a good idea to break it /* The cache is 512k. It might be a good idea to break it
up into a pointer array (e.g. an 8-bit image?) */ up into a pointer array (e.g. an 8-bit image?) */
/* malloc check ok, small constant allocation */
palette->cache = (INT16*) malloc(entries * sizeof(INT16)); palette->cache = (INT16*) malloc(entries * sizeof(INT16));
if (!palette->cache) { if (!palette->cache) {
(void) ImagingError_MemoryError(); (void) ImagingError_MemoryError();

View File

@ -31,6 +31,11 @@
#include "QuantHash.h" #include "QuantHash.h"
#include "QuantHeap.h" #include "QuantHeap.h"
/* MSVC9.0 */
#ifndef UINT32_MAX
#define UINT32_MAX 0xffffffff
#endif
#define NO_OUTPUT #define NO_OUTPUT
typedef struct { typedef struct {
@ -150,6 +155,7 @@ create_pixel_hash(Pixel *pixelData,uint32_t nPixels)
uint32_t timer,timer2,timer3; uint32_t timer,timer2,timer3;
#endif #endif
/* malloc check ok, small constant allocation */
d=malloc(sizeof(PixelHashData)); d=malloc(sizeof(PixelHashData));
if (!d) return NULL; if (!d) return NULL;
hash=hashtable_new(pixel_hash,pixel_cmp); hash=hashtable_new(pixel_hash,pixel_cmp);
@ -234,6 +240,7 @@ hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *
PIXEL_SCALE(&pixel,&q,d->scale); PIXEL_SCALE(&pixel,&q,d->scale);
/* malloc check ok, small constant allocation */
p=malloc(sizeof(PixelList)); p=malloc(sizeof(PixelList));
if (!p) return; if (!p) return;
@ -557,6 +564,7 @@ split(BoxNode *node)
exit(1); exit(1);
} }
#endif #endif
/* malloc check ok, small constant allocation */
left=malloc(sizeof(BoxNode)); left=malloc(sizeof(BoxNode));
right=malloc(sizeof(BoxNode)); right=malloc(sizeof(BoxNode));
if (!left||!right) { if (!left||!right) {
@ -613,6 +621,7 @@ median_cut(PixelList *hl[3],
BoxNode *thisNode; BoxNode *thisNode;
h=ImagingQuantHeapNew(box_heap_cmp); h=ImagingQuantHeapNew(box_heap_cmp);
/* malloc check ok, small constant allocation */
root=malloc(sizeof(BoxNode)); root=malloc(sizeof(BoxNode));
if (!root) { ImagingQuantHeapFree(h); return NULL; } if (!root) { ImagingQuantHeapFree(h); return NULL; }
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
@ -954,15 +963,16 @@ compute_palette_from_median_cut(
uint32_t *count; uint32_t *count;
*palette=NULL; *palette=NULL;
if (!(count=malloc(sizeof(uint32_t)*nPaletteEntries))) { /* malloc check ok, using calloc */
if (!(count=calloc(nPaletteEntries, sizeof(uint32_t)))) {
return 0; return 0;
} }
memset(count,0,sizeof(uint32_t)*nPaletteEntries);
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
avg[i]=NULL; avg[i]=NULL;
} }
for(i=0;i<3;i++) { 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++) { for(i=0;i<3;i++) {
if (avg[i]) free (avg[i]); if (avg[i]) free (avg[i]);
} }
@ -970,9 +980,6 @@ compute_palette_from_median_cut(
return 0; return 0;
} }
} }
for(i=0;i<3;i++) {
memset(avg[i],0,sizeof(uint32_t)*nPaletteEntries);
}
for (i=0;i<nPixels;i++) { for (i=0;i<nPixels;i++) {
#ifdef TEST_SPLIT_INTEGRITY #ifdef TEST_SPLIT_INTEGRITY
if (!(i%100)) { printf ("%05d\r",i); fflush(stdout); } if (!(i%100)) { printf ("%05d\r",i); fflush(stdout); }
@ -1004,7 +1011,8 @@ compute_palette_from_median_cut(
avg[2][paletteEntry]+=pixelData[i].c.b; avg[2][paletteEntry]+=pixelData[i].c.b;
count[paletteEntry]++; count[paletteEntry]++;
} }
p=malloc(sizeof(Pixel)*nPaletteEntries); /* malloc check ok, using calloc */
p=calloc(nPaletteEntries, sizeof(Pixel));
if (!p) { if (!p) {
for(i=0;i<3;i++) free (avg[i]); for(i=0;i<3;i++) free (avg[i]);
free(count); free(count);
@ -1090,21 +1098,33 @@ k_means(Pixel *pixelData,
int changes; int changes;
int built=0; int built=0;
if (!(count=malloc(sizeof(uint32_t)*nPaletteEntries))) { if (nPaletteEntries > UINT32_MAX / (sizeof(uint32_t))) {
return 0;
}
/* malloc check ok, using calloc */
if (!(count=calloc(nPaletteEntries, sizeof(uint32_t)))) {
return 0; return 0;
} }
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
avg[i]=NULL; avg[i]=NULL;
} }
for(i=0;i<3;i++) { 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)))) {
goto error_1; goto error_1;
} }
} }
avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries);
/* this is enough of a check, since the multiplication n*size is done above */
if (nPaletteEntries > UINT32_MAX / nPaletteEntries) {
goto error_1;
}
/* malloc check ok, using calloc, checking n*n above */
avgDist=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t));
if (!avgDist) { goto error_1; } 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; } if (!avgDistSortKey) { goto error_2; }
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
@ -1251,13 +1271,19 @@ quantize(Pixel *pixelData,
free_box_tree(root); free_box_tree(root);
root=NULL; 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; } if (!qp) { goto error_4; }
avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries); if (nPaletteEntries > UINT32_MAX / nPaletteEntries ) {
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; } 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 (!avgDistSortKey) { goto error_6; }
if (!build_distance_tables(avgDist,avgDistSortKey,p,nPaletteEntries)) { if (!build_distance_tables(avgDist,avgDistSortKey,p,nPaletteEntries)) {
@ -1400,7 +1426,8 @@ quantize2(Pixel *pixelData,
uint32_t *avgDist; uint32_t *avgDist;
uint32_t **avgDistSortKey; uint32_t **avgDistSortKey;
p=malloc(sizeof(Pixel)*nQuantPixels); /* malloc check ok, using calloc */
p=calloc(nQuantPixels, sizeof(Pixel));
if (!p) return 0; if (!p) return 0;
mean[0]=mean[1]=mean[2]=0; mean[0]=mean[1]=mean[2]=0;
h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
@ -1422,13 +1449,20 @@ quantize2(Pixel *pixelData,
} }
hashtable_free(h); 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; } if (!qp) { goto error_1; }
avgDist=malloc(sizeof(uint32_t)*nQuantPixels*nQuantPixels); if (nQuantPixels > UINT32_MAX / nQuantPixels ) {
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; } 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 (!avgDistSortKey) { goto error_3; }
if (!build_distance_tables(avgDist,avgDistSortKey,p,nQuantPixels)) { if (!build_distance_tables(avgDist,avgDistSortKey,p,nQuantPixels)) {
@ -1488,7 +1522,11 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
if (!strcmp(im->mode, "RGBA") && mode != 2 && mode != 3) if (!strcmp(im->mode, "RGBA") && mode != 2 && mode != 3)
return ImagingError_ModeError(); return ImagingError_ModeError();
p = malloc(sizeof(Pixel) * im->xsize * im->ysize); if (im->xsize > INT_MAX / im->ysize) {
return ImagingError_MemoryError();
}
/* malloc check ok, using calloc for final overflow, x*y above */
p = calloc(im->xsize * im->ysize, sizeof(Pixel));
if (!p) if (!p)
return ImagingError_MemoryError(); return ImagingError_MemoryError();

View File

@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <limits.h>
#include "QuantHeap.h" #include "QuantHeap.h"
@ -47,7 +48,12 @@ static int _heap_grow(Heap *h,int newsize) {
void *newheap; void *newheap;
if (!newsize) newsize=h->heapsize<<1; if (!newsize) newsize=h->heapsize<<1;
if (newsize<h->heapsize) return 0; if (newsize<h->heapsize) return 0;
newheap=malloc(sizeof(void *)*newsize); if (newsize > INT_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; if (!newheap) return 0;
memcpy(newheap,h->heap,sizeof(void *)*h->heapsize); memcpy(newheap,h->heap,sizeof(void *)*h->heapsize);
free(h->heap); free(h->heap);
@ -132,11 +138,16 @@ int ImagingQuantHeapTop(Heap *h,void **r) {
Heap *ImagingQuantHeapNew(HeapCmpFunc cf) { Heap *ImagingQuantHeapNew(HeapCmpFunc cf) {
Heap *h; Heap *h;
/* malloc check ok, small constant allocation */
h=malloc(sizeof(Heap)); h=malloc(sizeof(Heap));
if (!h) return NULL; if (!h) return NULL;
h->heapsize=INITIAL_SIZE; h->heapsize=INITIAL_SIZE;
h->heap=malloc(sizeof(void *)*h->heapsize); /* malloc check ok, using calloc for overflow */
if (!h->heap) { free(h); return NULL; } h->heap=calloc(h->heapsize, sizeof(void *));
if (!h->heap) {
free(h);
return NULL;
}
h->heapcount=0; h->heapcount=0;
h->cf=cf; h->cf=cf;
return h; return h;

View File

@ -26,6 +26,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include "QuantOctree.h" #include "QuantOctree.h"
@ -53,6 +54,7 @@ static ColorCube
new_color_cube(int r, int g, int b, int a) { new_color_cube(int r, int g, int b, int a) {
ColorCube cube; ColorCube cube;
/* malloc check ok, small constant allocation */
cube = malloc(sizeof(struct _ColorCube)); cube = malloc(sizeof(struct _ColorCube));
if (!cube) return NULL; if (!cube) return NULL;
@ -61,6 +63,12 @@ new_color_cube(int r, int g, int b, int a) {
cube->bBits = MAX(b, 0); cube->bBits = MAX(b, 0);
cube->aBits = MAX(a, 0); cube->aBits = MAX(a, 0);
/* overflow check for size multiplication below */
if (cube->rBits + cube->gBits + cube->bBits + cube->aBits > 31) {
free(cube);
return NULL;
}
/* the width of the cube for each dimension */ /* the width of the cube for each dimension */
cube->rWidth = 1<<cube->rBits; cube->rWidth = 1<<cube->rBits;
cube->gWidth = 1<<cube->gBits; cube->gWidth = 1<<cube->gBits;
@ -76,6 +84,7 @@ new_color_cube(int r, int g, int b, int a) {
/* the number of color buckets */ /* the number of color buckets */
cube->size = cube->rWidth * cube->gWidth * cube->bWidth * cube->aWidth; cube->size = cube->rWidth * cube->gWidth * cube->bWidth * cube->aWidth;
/* malloc check ok, overflow checked above */
cube->buckets = calloc(cube->size, sizeof(struct _ColorBucket)); cube->buckets = calloc(cube->size, sizeof(struct _ColorBucket));
if (!cube->buckets) { if (!cube->buckets) {
@ -154,7 +163,11 @@ compare_bucket_count(const ColorBucket a, const ColorBucket b) {
static ColorBucket static ColorBucket
create_sorted_color_palette(const ColorCube cube) { create_sorted_color_palette(const ColorCube cube) {
ColorBucket buckets; ColorBucket buckets;
buckets = malloc(sizeof(struct _ColorBucket)*cube->size); if (cube->size > LONG_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; if (!buckets) return NULL;
memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket)*cube->size); memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket)*cube->size);
@ -280,7 +293,15 @@ void add_lookup_buckets(ColorCube cube, ColorBucket palette, long nColors, long
ColorBucket ColorBucket
combined_palette(ColorBucket bucketsA, long nBucketsA, ColorBucket bucketsB, long nBucketsB) { combined_palette(ColorBucket bucketsA, long nBucketsA, ColorBucket bucketsB, long nBucketsB) {
ColorBucket result; ColorBucket result;
result = malloc(sizeof(struct _ColorBucket)*(nBucketsA+nBucketsB)); if (nBucketsA > LONG_MAX - nBucketsB ||
(nBucketsA+nBucketsB) > LONG_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, bucketsA, sizeof(struct _ColorBucket) * nBucketsA);
memcpy(&result[nBucketsA], bucketsB, sizeof(struct _ColorBucket) * nBucketsB); memcpy(&result[nBucketsA], bucketsB, sizeof(struct _ColorBucket) * nBucketsB);
return result; return result;
@ -291,7 +312,8 @@ create_palette_array(const ColorBucket palette, unsigned int paletteLength) {
Pixel *paletteArray; Pixel *paletteArray;
unsigned int i; unsigned int i;
paletteArray = malloc(sizeof(Pixel)*paletteLength); /* malloc check ok, calloc for overflow */
paletteArray = calloc(paletteLength, sizeof(Pixel));
if (!paletteArray) return NULL; if (!paletteArray) return NULL;
for (i=0; i<paletteLength; i++) { for (i=0; i<paletteLength; i++) {
@ -405,6 +427,7 @@ int quantize_octree(Pixel *pixelData,
paletteBucketsFine = NULL; paletteBucketsFine = NULL;
free(paletteBucketsCoarse); free(paletteBucketsCoarse);
paletteBucketsCoarse = NULL; paletteBucketsCoarse = NULL;
if (!paletteBuckets) goto error;
/* add all coarse colors to our coarse lookup cube. */ /* add all coarse colors to our coarse lookup cube. */
coarseLookupCube = new_color_cube(cubeBits[4], cubeBits[5], coarseLookupCube = new_color_cube(cubeBits[4], cubeBits[5],
@ -422,7 +445,8 @@ int quantize_octree(Pixel *pixelData,
add_lookup_buckets(lookupCube, paletteBuckets, nFineColors, nCoarseColors); add_lookup_buckets(lookupCube, paletteBuckets, nFineColors, nCoarseColors);
/* create result pixels and map palette indices */ /* create result pixels and map palette indices */
qp = malloc(sizeof(Pixel)*nPixels); /* malloc check ok, calloc for overflow */
qp = calloc(nPixels, sizeof(Pixel));
if (!qp) goto error; if (!qp) goto error;
map_image_pixels(pixelData, nPixels, lookupCube, qp); map_image_pixels(pixelData, nPixels, lookupCube, qp);

View File

@ -60,6 +60,12 @@ ImagingRankFilter(Imaging im, int size, int rank)
if (!(size & 1)) if (!(size & 1))
return (Imaging) ImagingError_ValueError("bad filter size"); return (Imaging) ImagingError_ValueError("bad filter size");
/* malloc check ok, for overflow in the define below */
if (size > INT_MAX / size ||
size > INT_MAX / (size * sizeof(FLOAT32))) {
return (Imaging) ImagingError_ValueError("filter size too large");
}
size2 = size * size; size2 = size * size;
margin = (size-1) / 2; margin = (size-1) / 2;
@ -70,6 +76,7 @@ ImagingRankFilter(Imaging im, int size, int rank)
if (!imOut) if (!imOut)
return NULL; return NULL;
/* malloc check ok, checked above */
#define RANK_BODY(type) do {\ #define RANK_BODY(type) do {\
type* buf = malloc(size2 * sizeof(type));\ type* buf = malloc(size2 * sizeof(type));\
if (!buf)\ if (!buf)\

View File

@ -98,15 +98,13 @@ ImagingPrecompute(int inSize, int outSize, struct filter *filterp,
if (outSize > INT_MAX / (kmax * sizeof(double))) if (outSize > INT_MAX / (kmax * sizeof(double)))
return 0; return 0;
// sizeof(double) should be greater than 0 as well
if (outSize > INT_MAX / (2 * sizeof(double)))
return 0;
/* coefficient buffer */ /* coefficient buffer */
/* malloc check ok, overflow checked above */
kk = malloc(outSize * kmax * sizeof(double)); kk = malloc(outSize * kmax * sizeof(double));
if ( ! kk) if ( ! kk)
return 0; return 0;
/* malloc check ok, kmax*sizeof(double) > 2*sizeof(int) */
xbounds = malloc(outSize * 2 * sizeof(int)); xbounds = malloc(outSize * 2 * sizeof(int));
if ( ! xbounds) { if ( ! xbounds) {
free(kk); free(kk);

View File

@ -46,7 +46,7 @@ int ImagingNewCount = 0;
*/ */
Imaging Imaging
ImagingNewPrologueSubtype(const char *mode, unsigned xsize, unsigned ysize, ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize,
int size) int size)
{ {
Imaging im; Imaging im;
@ -56,6 +56,11 @@ ImagingNewPrologueSubtype(const char *mode, unsigned xsize, unsigned ysize,
if (!im) if (!im)
return (Imaging) ImagingError_MemoryError(); return (Imaging) ImagingError_MemoryError();
/* linesize overflow check, roughly the current largest space req'd */
if (xsize > (INT_MAX / 4) - 1) {
return (Imaging) ImagingError_MemoryError();
}
/* Setup image descriptor */ /* Setup image descriptor */
im->xsize = xsize; im->xsize = xsize;
im->ysize = ysize; im->ysize = ysize;
@ -226,7 +231,7 @@ ImagingNewPrologueSubtype(const char *mode, unsigned xsize, unsigned ysize,
} }
Imaging Imaging
ImagingNewPrologue(const char *mode, unsigned xsize, unsigned ysize) ImagingNewPrologue(const char *mode, int xsize, int ysize)
{ {
return ImagingNewPrologueSubtype( return ImagingNewPrologueSubtype(
mode, xsize, ysize, sizeof(struct ImagingMemoryInstance) mode, xsize, ysize, sizeof(struct ImagingMemoryInstance)
@ -306,7 +311,8 @@ ImagingNewArray(const char *mode, int xsize, int ysize)
/* Allocate image as an array of lines */ /* Allocate image as an array of lines */
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
p = (char *) malloc(im->linesize); /* malloc check linesize checked in prologue */
p = (char *) calloc(1, im->linesize);
if (!p) { if (!p) {
ImagingDestroyArray(im); ImagingDestroyArray(im);
break; break;
@ -339,24 +345,32 @@ ImagingNewBlock(const char *mode, int xsize, int ysize)
{ {
Imaging im; Imaging im;
Py_ssize_t y, i; Py_ssize_t y, i;
Py_ssize_t bytes;
im = ImagingNewPrologue(mode, xsize, ysize); im = ImagingNewPrologue(mode, xsize, ysize);
if (!im) if (!im)
return NULL; return NULL;
/* Use a single block */ /* We shouldn't overflow, since the threshold defined
bytes = (Py_ssize_t) im->ysize * im->linesize; below says that we're only going to allocate max 4M
if (bytes <= 0) here before going to the array allocator. Check anyway.
*/
if (im->linesize &&
im->ysize > INT_MAX / im->linesize) {
/* punt if we're going to overflow */
return NULL;
}
if (im->ysize * im->linesize <= 0) {
/* some platforms return NULL for malloc(0); this fix /* some platforms return NULL for malloc(0); this fix
prevents MemoryError on zero-sized images on such prevents MemoryError on zero-sized images on such
platforms */ platforms */
bytes = 1; im->block = (char *) malloc(1);
im->block = (char *) malloc(bytes); } else {
/* malloc check ok, overflow check above */
im->block = (char *) calloc(im->ysize, im->linesize);
}
if (im->block) { if (im->block) {
memset(im->block, 0, bytes);
for (y = i = 0; y < im->ysize; y++) { for (y = i = 0; y < im->ysize; y++) {
im->image[y] = im->block + i; im->image[y] = im->block + i;
i += im->linesize; i += im->linesize;
@ -392,7 +406,7 @@ ImagingNew(const char* mode, int xsize, int ysize)
} else } else
bytes = strlen(mode); /* close enough */ 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); im = ImagingNewBlock(mode, xsize, ysize);
if (im) if (im)
return im; return im;

View File

@ -58,10 +58,14 @@ tsize_t _tiffWriteProc(thandle_t hdata, tdata_t buf, tsize_t size) {
tdata_t new; tdata_t new;
tsize_t newsize=state->size; tsize_t newsize=state->size;
while (newsize < (size + state->size)) { while (newsize < (size + state->size)) {
if (newsize > (tsize_t)SIZE_MAX - 64*1024){
return 0;
}
newsize += 64*1024; newsize += 64*1024;
// newsize*=2; // UNDONE, by 64k chunks? // newsize*=2; // UNDONE, by 64k chunks?
} }
TRACE(("Reallocing in write to %d bytes\n", (int)newsize)); TRACE(("Reallocing in write to %d bytes\n", (int)newsize));
/* malloc check ok, overflow checked above */
new = realloc(state->data, newsize); new = realloc(state->data, newsize);
if (!new) { if (!new) {
// fail out // fail out
@ -305,6 +309,7 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
} else { } else {
// malloc a buffer to write the tif, we're going to need to realloc or something if we need bigger. // 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")); TRACE(("Opening a buffer for writing \n"));
/* malloc check ok, small constant allocation */
clientstate->data = malloc(bufsize); clientstate->data = malloc(bufsize);
clientstate->size = bufsize; clientstate->size = bufsize;
clientstate->flrealloc=1; clientstate->flrealloc=1;

View File

@ -56,9 +56,15 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE)
context->prefix = 1; /* PNG */ context->prefix = 1; /* PNG */
/* overflow check for malloc */
if (state->bytes > INT_MAX - 1) {
state->errcode = IMAGING_CODEC_MEMORY;
return -1;
}
/* Expand standard buffer to make room for the (optional) filter /* Expand standard buffer to make room for the (optional) filter
prefix, and allocate a buffer to hold the previous line */ prefix, and allocate a buffer to hold the previous line */
free(state->buffer); free(state->buffer);
/* malloc check ok, overflow checked above */
state->buffer = (UINT8*) malloc(state->bytes+1); state->buffer = (UINT8*) malloc(state->bytes+1);
context->previous = (UINT8*) malloc(state->bytes+1); context->previous = (UINT8*) malloc(state->bytes+1);
if (!state->buffer || !context->previous) { if (!state->buffer || !context->previous) {

View File

@ -37,9 +37,16 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
/* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */ /* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */
/* overflow check for malloc */
if (state->bytes > INT_MAX - 1) {
state->errcode = IMAGING_CODEC_MEMORY;
return -1;
}
/* Expand standard buffer to make room for the filter selector, /* Expand standard buffer to make room for the filter selector,
and allocate filter buffers */ and allocate filter buffers */
free(state->buffer); free(state->buffer);
/* malloc check ok, overflow checked above */
state->buffer = (UINT8*) malloc(state->bytes+1); state->buffer = (UINT8*) malloc(state->bytes+1);
context->previous = (UINT8*) malloc(state->bytes+1); context->previous = (UINT8*) malloc(state->bytes+1);
context->prior = (UINT8*) malloc(state->bytes+1); context->prior = (UINT8*) malloc(state->bytes+1);
@ -341,6 +348,24 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
return -1; return -1;
} }
/* -------------------------------------------------------------------- */
/* Cleanup */
/* -------------------------------------------------------------------- */
int
ImagingZipEncodeCleanup(ImagingCodecState state) {
ZIPSTATE* context = (ZIPSTATE*) state->context;
if (context->dictionary) {
free (context->dictionary);
context->dictionary = NULL;
}
return -1;
}
const char* const char*
ImagingZipVersion(void) ImagingZipVersion(void)
{ {

19
path.c
View File

@ -107,10 +107,10 @@ path_dealloc(PyPathObject* path)
#define PyPath_Check(op) (Py_TYPE(op) == &PyPathType) #define PyPath_Check(op) (Py_TYPE(op) == &PyPathType)
int Py_ssize_t
PyPath_Flatten(PyObject* data, double **pxy) PyPath_Flatten(PyObject* data, double **pxy)
{ {
int i, j, n; Py_ssize_t i, j, n;
double *xy; double *xy;
if (PyPath_Check(data)) { if (PyPath_Check(data)) {
@ -283,7 +283,7 @@ path_compact(PyPathObject* self, PyObject* args)
/* Simple-minded method to shorten path. A point is removed if /* Simple-minded method to shorten path. A point is removed if
the city block distance to the previous point is less than the the city block distance to the previous point is less than the
given distance */ given distance */
int i, j; Py_ssize_t i, j;
double *xy; double *xy;
double cityblock = 2.0; double cityblock = 2.0;
@ -306,6 +306,7 @@ path_compact(PyPathObject* self, PyObject* args)
self->count = j; self->count = j;
/* shrink coordinate array */ /* shrink coordinate array */
/* malloc check ok, self->count is smaller than it was before */
self->xy = realloc(self->xy, 2 * self->count * sizeof(double)); self->xy = realloc(self->xy, 2 * self->count * sizeof(double));
return Py_BuildValue("i", i); /* number of removed vertices */ return Py_BuildValue("i", i); /* number of removed vertices */
@ -331,7 +332,7 @@ static PyObject*
path_getbbox(PyPathObject* self, PyObject* args) path_getbbox(PyPathObject* self, PyObject* args)
{ {
/* Find bounding box */ /* Find bounding box */
int i; Py_ssize_t i;
double *xy; double *xy;
double x0, y0, x1, y1; double x0, y0, x1, y1;
@ -358,7 +359,7 @@ path_getbbox(PyPathObject* self, PyObject* args)
} }
static PyObject* static PyObject*
path_getitem(PyPathObject* self, int i) path_getitem(PyPathObject* self, Py_ssize_t i)
{ {
if (i < 0) if (i < 0)
i = self->count + i; i = self->count + i;
@ -398,7 +399,7 @@ static PyObject*
path_map(PyPathObject* self, PyObject* args) path_map(PyPathObject* self, PyObject* args)
{ {
/* Map coordinate set through function */ /* Map coordinate set through function */
int i; Py_ssize_t i;
double *xy; double *xy;
PyObject* function; PyObject* function;
@ -426,7 +427,7 @@ path_map(PyPathObject* self, PyObject* args)
} }
static int static int
path_setitem(PyPathObject* self, int i, PyObject* op) path_setitem(PyPathObject* self, Py_ssize_t i, PyObject* op)
{ {
double* xy; double* xy;
@ -454,7 +455,7 @@ static PyObject*
path_tolist(PyPathObject* self, PyObject* args) path_tolist(PyPathObject* self, PyObject* args)
{ {
PyObject *list; PyObject *list;
int i; Py_ssize_t i;
int flat = 0; int flat = 0;
if (!PyArg_ParseTuple(args, "|i:tolist", &flat)) if (!PyArg_ParseTuple(args, "|i:tolist", &flat))
@ -491,7 +492,7 @@ static PyObject*
path_transform(PyPathObject* self, PyObject* args) path_transform(PyPathObject* self, PyObject* args)
{ {
/* Apply affine transform to coordinate set */ /* Apply affine transform to coordinate set */
int i; Py_ssize_t i;
double *xy; double *xy;
double a, b, c, d, e, f; double a, b, c, d, e, f;