Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

- added integer overflow checks to many memory allocation calls

  • Loading branch information...
commit f0960b14ef3c415ec87e69c8636fc81737099b48 1 parent 9cef844
Tony Cook authored
View
1  Changes
@@ -1206,6 +1206,7 @@ Revision history for Perl extension Imager.
- more examples
- add AUTHOR, REVISION.
- add smoke test for nearest_color filter
+- added integer overflow checks to many memory allocation calls
=================================================================
View
76 bmp.c
@@ -413,6 +413,7 @@ write_1bit_data(io_glue *ig, i_img *im) {
unsigned char *out;
int line_size = (im->xsize+7) / 8;
int x, y;
+ int unpacked_size;
/* round up to nearest multiple of four */
line_size = (line_size + 3) / 4 * 4;
@@ -420,10 +421,18 @@ write_1bit_data(io_glue *ig, i_img *im) {
if (!write_bmphead(ig, im, 1, line_size * im->ysize))
return 0;
- line = mymalloc(im->xsize + 8);
+ /* this shouldn't be an issue, but let's be careful */
+ unpacked_size = im->xsize + 8;
+ if (unpacked_size < im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
+ line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
memset(line + im->xsize, 0, 8);
-
- packed = mymalloc(line_size);
+
+ /* size allocated here is always much smaller than xsize, hence
+ can't overflow int */
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
memset(packed, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
@@ -474,6 +483,7 @@ write_4bit_data(io_glue *ig, i_img *im) {
unsigned char *out;
int line_size = (im->xsize+1) / 2;
int x, y;
+ int unpacked_size;
/* round up to nearest multiple of four */
line_size = (line_size + 3) / 4 * 4;
@@ -481,10 +491,18 @@ write_4bit_data(io_glue *ig, i_img *im) {
if (!write_bmphead(ig, im, 4, line_size * im->ysize))
return 0;
- line = mymalloc(im->xsize + 2);
+ /* this shouldn't be an issue, but let's be careful */
+ unpacked_size = im->xsize + 2;
+ if (unpacked_size < im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
+ line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
memset(line + im->xsize, 0, 2);
- packed = mymalloc(line_size);
+ /* size allocated here is always much smaller than xsize, hence
+ can't overflow int */
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
memset(packed, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
@@ -522,6 +540,7 @@ write_8bit_data(io_glue *ig, i_img *im) {
i_palidx *line;
int line_size = im->xsize;
int y;
+ int unpacked_size;
/* round up to nearest multiple of four */
line_size = (line_size + 3) / 4 * 4;
@@ -529,7 +548,13 @@ write_8bit_data(io_glue *ig, i_img *im) {
if (!write_bmphead(ig, im, 8, line_size * im->ysize))
return 0;
- line = mymalloc(im->xsize + 4);
+ /* this shouldn't be an issue, but let's be careful */
+ unpacked_size = im->xsize + 4;
+ if (unpacked_size < im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
+ line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
memset(line + im->xsize, 0, 4);
for (y = im->ysize-1; y >= 0; --y) {
@@ -565,13 +590,20 @@ write_24bit_data(io_glue *ig, i_img *im) {
unsigned char *samples;
int y;
int line_size = 3 * im->xsize;
+
+ /* just in case we implement a direct format with 2bytes/pixel
+ (unlikely though) */
+ if (line_size / 3 != im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
line_size = (line_size + 3) / 4 * 4;
if (!write_bmphead(ig, im, 24, line_size * im->ysize))
return 0;
chans = im->channels >= 3 ? bgr_chans : grey_chans;
- samples = mymalloc(line_size);
+ samples = mymalloc(line_size); /* checked 29jun05 tonyc */
memset(samples, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
i_gsamp(im, 0, im->xsize, y, samples, chans, 3);
@@ -646,6 +678,15 @@ read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
return NULL;
}
+ if (xsize + 8 < xsize) { /* if there was overflow */
+ /* we check with 8 because we allocate that much for the decoded
+ line buffer */
+ i_push_error(0, "integer overflow during memory allocation");
+ return NULL;
+ }
+
+ /* if xsize+7 is ok then (xsize+7)/8 will be and the minor
+ adjustments below won't make it overflow */
line_size = (line_size+3) / 4 * 4;
if (ysize > 0) {
@@ -697,8 +738,8 @@ read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
- packed = mymalloc(line_size);
- line = mymalloc(xsize+8);
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
+ line = mymalloc(xsize+8); /* checked 29jun05 tonyc */
while (y != lasty) {
if (ig->readcb(ig, packed, line_size) != line_size) {
myfree(packed);
@@ -751,6 +792,8 @@ read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
int size, i;
long base_offset;
+ /* line_size is going to be smaller than xsize in most cases (and
+ when it's not, xsize is itself small), and hence not overflow */
line_size = (line_size+3) / 4 * 4;
if (ysize > 0) {
@@ -802,10 +845,11 @@ read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
}
if (line_size < 260)
- packed = mymalloc(260);
+ packed = mymalloc(260); /* checked 29jun05 tonyc */
else
- packed = mymalloc(line_size);
- line = mymalloc(xsize+1);
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
+ /* xsize won't approach MAXINT */
+ line = mymalloc(xsize+1); /* checked 29jun05 tonyc */
if (compression == BI_RGB) {
i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
while (y != lasty) {
@@ -930,6 +974,10 @@ read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
long base_offset;
line_size = (line_size+3) / 4 * 4;
+ if (line_size < xsize) { /* if it overflowed (unlikely, but check) */
+ i_push_error(0, "integer overflow during memory allocation");
+ return NULL;
+ }
if (ysize > 0) {
y = ysize-1;
@@ -978,7 +1026,7 @@ read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
}
}
- line = mymalloc(line_size);
+ line = mymalloc(line_size); /* checked 29jun05 tonyc */
if (compression == BI_RGB) {
i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
while (y != lasty) {
@@ -1191,7 +1239,7 @@ read_direct_bmp(io_glue *ig, int xsize, int ysize, int bit_count,
i_push_error(0, "integer overflow calculating buffer size");
return NULL;
}
- line = mymalloc(bytes);
+ line = mymalloc(bytes); /* checked 29jun05 tonyc */
while (y != lasty) {
p = line;
for (x = 0; x < xsize; ++x) {
View
19 convert.c
@@ -68,8 +68,9 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
}
if (im->bits == i_8_bits && src->bits == i_8_bits) {
i_color *vals;
-
- vals = mymalloc(sizeof(i_color) * src->xsize);
+
+ /* we can always allocate a single scanline of i_color */
+ vals = mymalloc(sizeof(i_color) * src->xsize); /* checked 04Jul05 tonyc */
for (y = 0; y < src->ysize; ++y) {
i_glin(src, 0, src->xsize, y, vals);
for (x = 0; x < src->xsize; ++x) {
@@ -97,8 +98,10 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
}
else {
i_fcolor *vals;
-
- vals = mymalloc(sizeof(i_fcolor) * src->xsize);
+
+ /* we can always allocate a single scanline of i_fcolor
+ for a >8 image */
+ vals = mymalloc(sizeof(i_fcolor) * src->xsize); /* checked 4Jul05 tonyc */
for (y = 0; y < src->ysize; ++y) {
i_glinf(src, 0, src->xsize, y, vals);
for (x = 0; x < src->xsize; ++x) {
@@ -142,7 +145,8 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
/* just translate the color table */
count = i_colorcount(src);
outcount = i_colorcount(im);
- colors = mymalloc(count * sizeof(i_color));
+ /* color table allocated for image, so it must fit */
+ colors = mymalloc(count * sizeof(i_color)); /* check 04Jul05 tonyc */
i_getcolors(src, 0, colors, count);
for (index = 0; index < count; ++index) {
for (j = 0; j < outchan; ++j) {
@@ -171,7 +175,10 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
i_addcolors(im, colors, count-outcount);
}
/* and copy the indicies */
- vals = mymalloc(sizeof(i_palidx) * im->xsize);
+ /* i_palidx is always unsigned char and will never be bigger than short
+ and since a line of 4-byte i_colors can fit then a line of i_palidx
+ will fit */
+ vals = mymalloc(sizeof(i_palidx) * im->xsize); /* checked 4jul05 tonyc */
for (y = 0; y < im->ysize; ++y) {
i_gpal(src, 0, im->xsize, y, vals);
i_ppal(im, 0, im->xsize, y, vals);
View
18 datatypes.c
@@ -12,9 +12,15 @@
struct i_bitmap*
btm_new(int xsize,int ysize) {
int i;
+ int bytes;
struct i_bitmap *btm;
- btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap));
- btm->data=(char*)mymalloc((xsize*ysize+8)/8);
+ btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
+ bytes = (xsize*ysize+8)/8;
+ if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
+ fprintf(stderr, "Integer overflow allocating bitmap %d x %d", xsize, ysize);
+ exit(3);
+ }
+ btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
btm->xsize=xsize;
btm->ysize=ysize;
for(i=0;i<(xsize*ysize+8)/8;i++) btm->data[i]=0; /* Is this always needed */
@@ -56,11 +62,11 @@ btm_set(struct i_bitmap *btm,int x,int y) {
struct llink *
llink_new(struct llink* p,int size) {
struct llink *l;
- l = mymalloc(sizeof(struct llink));
+ l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
l->n = NULL;
l->p = p;
l->fill = 0;
- l->data = mymalloc(size);
+ l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
return l;
}
@@ -97,7 +103,7 @@ llist_llink_push(struct llist *lst, struct llink *lnk,void *data) {
struct llist *
llist_new(int multip, int ssize) {
struct llist *l;
- l = mymalloc(sizeof(struct llist));
+ l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
l->h = NULL;
l->t = NULL;
l->multip = multip;
@@ -198,7 +204,7 @@ octt_new() {
int i;
struct octt *t;
- t=(struct octt*)mymalloc(sizeof(struct octt));
+ t=(struct octt*)mymalloc(sizeof(struct octt)); /* checked 4jul05 tonyc */
for(i=0;i<8;i++) t->t[i]=NULL;
t->cnt=0;
return t;
View
61 draw.c
@@ -8,9 +8,16 @@
void
i_mmarray_cr(i_mmarray *ar,int l) {
int i;
+ int alloc_size;
ar->lines=l;
- ar->data=mymalloc(sizeof(minmax)*l);
+ alloc_size = sizeof(minmax) * l;
+ /* check for overflow */
+ if (alloc_size / l != sizeof(minmax)) {
+ fprintf(stderr, "overflow calculating memory allocation");
+ exit(3);
+ }
+ ar->data=mymalloc(alloc_size); /* checked 5jul05 tonyc */
for(i=0;i<l;i++) { ar->data[i].max=-1; ar->data[i].min=MAXINT; }
}
@@ -51,10 +58,10 @@ void
i_mmarray_render_fill(i_img *im,i_mmarray *ar,i_fill_t *fill) {
int x, w, y;
if (im->bits == i_8_bits && fill->fill_with_color) {
- i_color *line = mymalloc(sizeof(i_color) * im->xsize);
+ i_color *line = mymalloc(sizeof(i_color) * im->xsize); /* checked 5jul05 tonyc */
i_color *work = NULL;
if (fill->combine)
- work = mymalloc(sizeof(i_color) * im->xsize);
+ work = mymalloc(sizeof(i_color) * im->xsize); /* checked 5jul05 tonyc */
for(y=0;y<ar->lines;y++) {
if (ar->data[y].max!=-1) {
x = ar->data[y].min;
@@ -77,10 +84,10 @@ i_mmarray_render_fill(i_img *im,i_mmarray *ar,i_fill_t *fill) {
myfree(work);
}
else {
- i_fcolor *line = mymalloc(sizeof(i_fcolor) * im->xsize);
+ i_fcolor *line = mymalloc(sizeof(i_fcolor) * im->xsize); /* checked 5jul05 tonyc */
i_fcolor *work = NULL;
if (fill->combinef)
- work = mymalloc(sizeof(i_fcolor) * im->xsize);
+ work = mymalloc(sizeof(i_fcolor) * im->xsize); /* checked 5jul05 tonyc */
for(y=0;y<ar->lines;y++) {
if (ar->data[y].max!=-1) {
x = ar->data[y].min;
@@ -492,11 +499,21 @@ i_box_cfill(i_img *im,int x1,int y1,int x2,int y2,i_fill_t *fill) {
mm_log((1,"i_box_cfill(im* 0x%x,x1 %d,y1 %d,x2 %d,y2 %d,fill 0x%x)\n",im,x1,y1,x2,y2,fill));
++x2;
+ if (x1 < 0)
+ x1 = 0;
+ if (y1 < 0)
+ y1 = 0;
+ if (x2 > im->xsize)
+ x2 = im->xsize;
+ if (y2 >= im->ysize)
+ y2 = im->ysize-1;
+ if (x1 >= x2 || y1 > y2)
+ return;
if (im->bits == i_8_bits && fill->fill_with_color) {
- i_color *line = mymalloc(sizeof(i_color) * (x2 - x1));
+ i_color *line = mymalloc(sizeof(i_color) * (x2 - x1)); /* checked 5jul05 tonyc */
i_color *work = NULL;
if (fill->combine)
- work = mymalloc(sizeof(i_color) * (x2-x1));
+ work = mymalloc(sizeof(i_color) * (x2-x1)); /* checked 5jul05 tonyc */
while (y1 <= y2) {
if (fill->combine) {
i_glin(im, x1, x2, y1, line);
@@ -514,9 +531,9 @@ i_box_cfill(i_img *im,int x1,int y1,int x2,int y2,i_fill_t *fill) {
myfree(work);
}
else {
- i_fcolor *line = mymalloc(sizeof(i_fcolor) * (x2 - x1));
+ i_fcolor *line = mymalloc(sizeof(i_fcolor) * (x2 - x1)); /* checked 5jul05 tonyc */
i_fcolor *work;
- work = mymalloc(sizeof(i_fcolor) * (x2 - x1));
+ work = mymalloc(sizeof(i_fcolor) * (x2 - x1)); /* checked 5jul05 tonyc */
while (y1 <= y2) {
if (fill->combine) {
@@ -894,8 +911,8 @@ i_bezier_multi(i_img *im,int l,double *x,double *y,i_color *val) {
int n=l-1;
double itr,ccoef;
-
- bzcoef=mymalloc(sizeof(double)*l);
+ /* this is the same size as the x and y arrays, so shouldn't overflow */
+ bzcoef=mymalloc(sizeof(double)*l); /* checked 5jul05 tonyc */
for(k=0;k<l;k++) bzcoef[k]=perm(n,k);
ICL_info(val);
@@ -926,16 +943,6 @@ i_bezier_multi(i_img *im,int l,double *x,double *y,i_color *val) {
myfree(bzcoef);
}
-
-
-
-
-
-
-
-
-
-
/* Flood fill
REF: Graphics Gems I. page 282+
@@ -983,7 +990,7 @@ static
struct stack_element*
crdata(int left,int right,int dadl,int dadr,int y, int dir) {
struct stack_element *ste;
- ste = mymalloc(sizeof(struct stack_element));
+ ste = mymalloc(sizeof(struct stack_element)); /* checked 5jul05 tonyc */
ste->myLx = left;
ste->myRx = right;
ste->dadLx = dadl;
@@ -1231,10 +1238,11 @@ i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill) {
btm = i_flood_fill_low(im, seedx, seedy, &bxmin, &bxmax, &bymin, &bymax);
if (im->bits == i_8_bits && fill->fill_with_color) {
- i_color *line = mymalloc(sizeof(i_color) * (bxmax - bxmin));
+ /* bxmax/bxmin are inside the image, hence this won't overflow */
+ i_color *line = mymalloc(sizeof(i_color) * (bxmax - bxmin)); /* checked 5jul05 tonyc */
i_color *work = NULL;
if (fill->combine)
- work = mymalloc(sizeof(i_color) * (bxmax - bxmin));
+ work = mymalloc(sizeof(i_color) * (bxmax - bxmin)); /* checked 5jul05 tonyc */
for(y=bymin; y<=bymax; y++) {
x = bxmin;
@@ -1266,10 +1274,11 @@ i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill) {
myfree(work);
}
else {
- i_fcolor *line = mymalloc(sizeof(i_fcolor) * (bxmax - bxmin));
+ /* bxmax/bxmin are inside the image, hence this won't overflow */
+ i_fcolor *line = mymalloc(sizeof(i_fcolor) * (bxmax - bxmin)); /* checked 5jul05 tonyc */
i_fcolor *work = NULL;
if (fill->combinef)
- work = mymalloc(sizeof(i_fcolor) * (bxmax - bxmin));
+ work = mymalloc(sizeof(i_fcolor) * (bxmax - bxmin)); /* checked 5jul05 tonyc */
for(y=bymin;y<=bymax;y++) {
x = bxmin;
View
15 error.c
@@ -95,7 +95,9 @@ void i_set_argv0(char const *name) {
char *dupl;
if (!name)
return;
- dupl = mymalloc(strlen(name)+1);
+ /* if the user has an existing string of MAXINT length then
+ the system is broken anyway */
+ dupl = mymalloc(strlen(name)+1); /* check 17jul05 tonyc */
strcpy(dupl, name);
if (argv0)
myfree(argv0);
@@ -222,9 +224,11 @@ void i_push_error(int code, char const *msg) {
if (error_space[error_sp] < size) {
if (error_stack[error_sp].msg)
myfree(error_stack[error_sp].msg);
- /* memory allocated on the following line is only ever release when
+ /* memory allocated on the following line is only ever released when
we need a bigger string */
- error_stack[error_sp].msg = mymalloc(size);
+ /* size is size (len+1) of an existing string, overflow would mean
+ the system is broken anyway */
+ error_stack[error_sp].msg = mymalloc(size); /* checked 17jul05 tonyc */
error_space[error_sp] = size;
}
strcpy(error_stack[error_sp].msg, msg);
@@ -270,6 +274,9 @@ void i_push_errorf(int code, char const *fmt, ...) {
va_end(ap);
}
+#ifdef IMAGER_I_FAILED
+#error "This isn't used and is untested"
+
/*
=item i_failed(char const *msg)
@@ -326,6 +333,8 @@ int i_failed(int code, char const *msg) {
return 0;
}
+#endif
+
/*
=back
View
8 fills.c
@@ -220,7 +220,7 @@ If combine is non-zero then alpha values will be combined.
i_fill_t *
i_new_fill_solidf(i_fcolor *c, int combine) {
int ch;
- i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t));
+ i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t)); /* checked 14jul05 tonyc */
if (combine) {
*fill = base_solid_fill_comb;
@@ -249,7 +249,7 @@ If combine is non-zero then alpha values will be combined.
i_fill_t *
i_new_fill_solid(i_color *c, int combine) {
int ch;
- i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t));
+ i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t)); /* checked 14jul05 tonyc */
if (combine) {
*fill = base_solid_fill_comb;
@@ -484,7 +484,7 @@ Create an image based fill.
*/
i_fill_t *
i_new_fill_image(i_img *im, double *matrix, int xoff, int yoff, int combine) {
- struct i_fill_image_t *fill = mymalloc(sizeof(*fill));
+ struct i_fill_image_t *fill = mymalloc(sizeof(*fill)); /* checked 14jul05 tonyc */
fill->base.fill_with_color = fill_image;
fill->base.fill_with_fcolor = fill_imagef;
@@ -599,7 +599,7 @@ i_fill_t *
i_new_hatch_low(i_color *fg, i_color *bg, i_fcolor *ffg, i_fcolor *fbg,
int combine, int hatch, unsigned char *cust_hatch,
int dx, int dy) {
- i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t));
+ i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t)); /* checked 14jul05 tonyc */
fill->base.fill_with_color = fill_hatch;
fill->base.fill_with_fcolor = fill_hatchf;
View
91 filters.c
@@ -937,6 +937,7 @@ i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
int channels = im->channels;
int xsize = im->xsize;
int ysize = im->ysize;
+ int bytes;
float *fdist;
@@ -947,7 +948,20 @@ i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
ICL_info(&ival[p]);
}
- fdist = mymalloc( sizeof(float) * num );
+ /* on the systems I have sizeof(float) == sizeof(int) and thus
+ this would be same size as the arrays xo and yo point at, but this
+ may not be true for other systems
+
+ since the arrays here are caller controlled, I assume that on
+ overflow is a programming error rather than an end-user error, so
+ calling exit() is justified.
+ */
+ bytes = sizeof(float) * num;
+ if (bytes / num != sizeof(float)) {
+ fprintf(stderr, "integer overflow calculating memory allocation");
+ exit(1);
+ }
+ fdist = mymalloc( bytes ); /* checked 14jul05 tonyc */
for(y = 0; y<ysize; y++) for(x = 0; x<xsize; x++) {
float cs = 0;
@@ -1047,6 +1061,72 @@ i_nearest_color_foo(i_img *im, int num, int *xo, int *yo, i_color *ival, int dme
}
}
+/*
+=item i_nearest_color(im, num, xo, yo, oval, dmeasure)
+
+This wasn't document - quoth Addi:
+
+ An arty type of filter
+
+FIXME: check IRC logs for actual text.
+
+Inputs:
+
+=over
+
+=item *
+
+i_img *im - image to render on.
+
+=item *
+
+int num - number of points/colors in xo, yo, oval
+
+=item *
+
+int *xo - array of I<num> x positions
+
+=item *
+
+int *yo - array of I<num> y positions
+
+=item *
+
+i_color *oval - array of I<num> colors
+
+xo, yo, oval correspond to each other, the point xo[i], yo[i] has a
+color something like oval[i], at least closer to that color than other
+points.
+
+=item *
+
+int dmeasure - how we measure the distance from some point P(x,y) to
+any (xo[i], yo[i]).
+
+Valid values are:
+
+=over
+
+=item 0
+
+euclidean distance: sqrt((x2-x1)**2 + (y2-y1)**2)
+
+=item 1
+
+square of euclidean distance: ((x2-x1)**2 + (y2-y1)**2)
+
+=item 2
+
+manhattan distance: max((y2-y1)**2, (x2-x1)**2)
+
+=back
+
+An invalid value causes an error exit (the program is aborted).
+
+=back
+
+=cut
+ */
void
i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasure) {
i_color *ival;
@@ -1058,7 +1138,7 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
int ysize = im->ysize;
int *cmatch;
- mm_log((1,"i_nearest_color(im %p, num %d, xo %p, yo %p, ival %p, dmeasure %d)\n", im, num, xo, yo, oval, dmeasure));
+ mm_log((1,"i_nearest_color(im %p, num %d, xo %p, yo %p, oval %p, dmeasure %d)\n", im, num, xo, yo, oval, dmeasure));
tval = mymalloc( sizeof(float)*num*im->channels );
ival = mymalloc( sizeof(i_color)*num );
@@ -1120,12 +1200,13 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
c1 = 1.0-c2;
for(ch = 0; ch<im->channels; ch++)
- tval[midx*im->channels + ch] = c1*tval[midx*im->channels + ch] + c2 * (float) val.channel[ch];
+ tval[midx*im->channels + ch] =
+ c1*tval[midx*im->channels + ch] + c2 * (float) val.channel[ch];
-
}
- for(p = 0; p<num; p++) for(ch = 0; ch<im->channels; ch++) ival[p].channel[ch] = tval[p*im->channels + ch];
+ for(p = 0; p<num; p++) for(ch = 0; ch<im->channels; ch++)
+ ival[p].channel[ch] = tval[p*im->channels + ch];
i_nearest_color_foo(im, num, xo, yo, ival, dmeasure);
}
View
12 font.c
@@ -461,7 +461,8 @@ Sets *outlen to the number of bytes used in the output string.
static char *
t1_from_utf8(char const *in, int len, int *outlen) {
- char *out = mymalloc(len+1);
+ /* at this point len is from a perl SV, so can't approach MAXINT */
+ char *out = mymalloc(len+1); /* checked 5Nov05 tonyc */
char *p = out;
unsigned long c;
@@ -992,7 +993,7 @@ i_tt_new(char *fontname) {
/* allocate memory for the structure */
- handle = mymalloc( sizeof(TT_Fonthandle) );
+ handle = mymalloc( sizeof(TT_Fonthandle) ); /* checked 5Nov05 tonyc */
/* load the typeface */
error = TT_Open_Face( engine, fontname, &handle->face );
@@ -1082,10 +1083,15 @@ i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth ) {
bit->cols = ( bit->width + 7 ) / 8; /* convert to # of bytes */
bit->size = bit->rows * bit->cols; /* number of bytes in buffer */
}
+
+ if (bit->size / bit->rows != bit->cols) {
+ m_fatal(0, "Integer overflow calculating bitmap size (%d, %d)\n",
+ bit->width, bit->rows);
+ }
mm_log((1,"i_tt_init_raster_map: bit->width %d, bit->cols %d, bit->rows %d, bit->size %d)\n", bit->width, bit->cols, bit->rows, bit->size ));
- bit->bitmap = (void *) mymalloc( bit->size );
+ bit->bitmap = (void *) mymalloc( bit->size ); /* checked 6Nov05 tonyc */
if ( !bit->bitmap ) m_fatal(0,"Not enough memory to allocate bitmap (%d)!\n",bit->size );
}
View
11 img16.c
@@ -143,7 +143,7 @@ Creates a new 16-bit per sample image.
=cut
*/
i_img *i_img_16_new_low(i_img *im, int x, int y, int ch) {
- int bytes;
+ int bytes, line_bytes;
mm_log((1,"i_img_16_new(x %d, y %d, ch %d)\n", x, y, ch));
if (x < 1 || y < 1) {
@@ -160,6 +160,15 @@ i_img *i_img_16_new_low(i_img *im, int x, int y, int ch) {
return NULL;
}
+ /* basic assumption: we can always allocate a buffer representing a
+ line from the image, otherwise we're going to have trouble
+ working with the image */
+ line_bytes = sizeof(i_fcolor) * x;
+ if (line_bytes / x != sizeof(i_fcolor)) {
+ i_push_error(0, "integer overflow calculating scanline allocation");
+ return NULL;
+ }
+
*im = IIM_base_16bit_direct;
i_tags_new(&im->tags);
im->xsize = x;
View
13 palimg.c
@@ -84,7 +84,7 @@ Currently 0 < maxpal <= 256
*/
i_img *i_img_pal_new_low(i_img *im, int x, int y, int channels, int maxpal) {
i_img_pal_ext *palext;
- int bytes;
+ int bytes, line_bytes;
i_clear_error();
if (maxpal < 1 || maxpal > 256) {
@@ -101,7 +101,16 @@ i_img *i_img_pal_new_low(i_img *im, int x, int y, int channels, int maxpal) {
}
bytes = sizeof(i_palidx) * x * y;
if (bytes / y / sizeof(i_palidx) != x) {
- i_push_errorf(0, "integer overflow calculating image allocation");
+ i_push_error(0, "integer overflow calculating image allocation");
+ return NULL;
+ }
+
+ /* basic assumption: we can always allocate a buffer representing a
+ line from the image, otherwise we're going to have trouble
+ working with the image */
+ line_bytes = sizeof(i_color) * x;
+ if (line_bytes / x != sizeof(i_color)) {
+ i_push_error(0, "integer overflow calculating scanline allocation");
return NULL;
}
View
13 t/t021sixteen.t
@@ -1,7 +1,7 @@
#!perl -w
use strict;
use lib 't';
-use Test::More tests => 83;
+use Test::More tests => 85;
BEGIN { use_ok(Imager=>qw(:all :handy)) }
@@ -132,6 +132,17 @@ cmp_ok(Imager->errstr, '=~', qr/channels must be between 1 and 4/,
cmp_ok(Imager->errstr, '=~', qr/integer overflow/,
"check the error message");
+
+ # check we can allocate a scanline, unlike double images the scanline
+ # in the image itself is smaller than a line of i_fcolor
+ # divide by 2 to get to int range, by 2 for 2 bytes/pixel, by 3 to
+ # fit the image allocation in, but for the floats to overflow
+ my $dim4 = $uint_range / 2 / 2 / 3;
+ my $im_o = Imager->new(xsize=>$dim4, ysize=>1, channels=>1, bits=>16);
+ is($im_o, undef, "integer overflow check - scanline");
+ cmp_ok(Imager->errstr, '=~',
+ qr/integer overflow calculating scanline allocation/,
+ "check error message");
}
}
View
18 t/t023palette.t
@@ -2,7 +2,7 @@
# some of this is tested in t01introvert.t too
use strict;
use lib 't';
-use Test::More tests => 62;
+use Test::More tests => 64;
BEGIN { use_ok("Imager"); }
my $img = Imager->new(xsize=>50, ysize=>50, type=>'paletted');
@@ -139,7 +139,7 @@ cmp_ok(Imager->errstr, '=~', qr/Channels must be positive and <= 4/,
use Config;
SKIP:
{
- skip("don't want to allocate 4Gb", 8)
+ skip("don't want to allocate 4Gb", 10)
unless $Config{intsize} == 4;
my $uint_range = 256 ** $Config{intsize};
@@ -164,13 +164,23 @@ cmp_ok(Imager->errstr, '=~', qr/Channels must be positive and <= 4/,
$im_b = Imager->new(xsize=>$dim3, ysize=>$dim3, channels=>3, type=>'paletted');
is($im_b, undef, "integer overflow check - 3 channel");
- $im_b = Imager->new(xisze=>$dim3, ysize=>1, channels=>3, type=>'paletted');
+ $im_b = Imager->new(xsize=>$dim3, ysize=>1, channels=>3, type=>'paletted');
ok($im_b, "but same width ok");
- $im_b = Imager->new(xisze=>1, ysize=>$dim3, channels=>3, type=>'paletted');
+ $im_b = Imager->new(xsize=>1, ysize=>$dim3, channels=>3, type=>'paletted');
ok($im_b, "but same height ok");
cmp_ok(Imager->errstr, '=~', qr/integer overflow/,
"check the error message");
+
+ # test the scanline allocation check
+ # divide by 2 to get int range, by 3 so that the image (one byte/pixel)
+ # doesn't integer overflow, but the scanline of i_color (4/pixel) does
+ my $dim4 = $uint_range / 2 / 3;
+ my $im_o = Imager->new(xsize=>$dim4, ysize=>1, channels=>3, type=>'paletted');
+ is($im_o, undef, "integer overflow check - scanline size");
+ cmp_ok(Imager->errstr, '=~',
+ qr/integer overflow calculating scanline allocation/,
+ "check error message");
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.