diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-11-27 23:31:30 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-11-27 23:31:30 +0100 |
| commit | 2e5ab1d9987831c981ff05862e8ccf1381ed58ea (patch) | |
| tree | d272374db43b0c5d498442f441feb2f43faf76dc /src | |
| parent | 92023cd6c377e0384a7725949b25655d4d94dced (diff) | |
color_apply_icc_profile: avoid potential heap buffer overflow
Derived from a patch by Thuan Pham
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/common/color.c | 154 |
1 files changed, 82 insertions, 72 deletions
diff --git a/src/bin/common/color.c b/src/bin/common/color.c index a97d49f1..d3a2f38d 100644 --- a/src/bin/common/color.c +++ b/src/bin/common/color.c @@ -597,82 +597,92 @@ void color_apply_icc_profile(opj_image_t *image) } if (image->numcomps > 2) { /* RGB, RGBA */ - if (prec <= 8) { - unsigned char *inbuf, *outbuf, *in, *out; - - max = max_w * max_h; - nr_samples = (size_t)(max * 3U * sizeof(unsigned char)); - in = inbuf = (unsigned char*)opj_image_data_alloc(nr_samples); - out = outbuf = (unsigned char*)opj_image_data_alloc(nr_samples); - - if (inbuf == NULL || outbuf == NULL) { - goto fails0; - } - - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - - for (i = 0U; i < max; ++i) { - *in++ = (unsigned char) * r++; - *in++ = (unsigned char) * g++; - *in++ = (unsigned char) * b++; - } - - cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); - - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - - for (i = 0U; i < max; ++i) { - *r++ = (int) * out++; - *g++ = (int) * out++; - *b++ = (int) * out++; - } - ok = 1; + if ((image->comps[0].w == image->comps[1].w && + image->comps[0].w == image->comps[2].w) && + (image->comps[0].h == image->comps[1].h && + image->comps[0].h == image->comps[2].h)) { + if (prec <= 8) { + unsigned char *inbuf, *outbuf, *in, *out; + + max = max_w * max_h; + nr_samples = (size_t)(max * 3U * sizeof(unsigned char)); + in = inbuf = (unsigned char*)opj_image_data_alloc(nr_samples); + out = outbuf = (unsigned char*)opj_image_data_alloc(nr_samples); + + if (inbuf == NULL || outbuf == NULL) { + goto fails0; + } + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + for (i = 0U; i < max; ++i) { + *in++ = (unsigned char) * r++; + *in++ = (unsigned char) * g++; + *in++ = (unsigned char) * b++; + } + + cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + for (i = 0U; i < max; ++i) { + *r++ = (int) * out++; + *g++ = (int) * out++; + *b++ = (int) * out++; + } + ok = 1; fails0: - opj_image_data_free(inbuf); - opj_image_data_free(outbuf); - } else { /* prec > 8 */ - unsigned short *inbuf, *outbuf, *in, *out; - - max = max_w * max_h; - nr_samples = (size_t)(max * 3U * sizeof(unsigned short)); - in = inbuf = (unsigned short*)opj_image_data_alloc(nr_samples); - out = outbuf = (unsigned short*)opj_image_data_alloc(nr_samples); - - if (inbuf == NULL || outbuf == NULL) { - goto fails1; - } - - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - - for (i = 0U ; i < max; ++i) { - *in++ = (unsigned short) * r++; - *in++ = (unsigned short) * g++; - *in++ = (unsigned short) * b++; - } - - cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); - - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - - for (i = 0; i < max; ++i) { - *r++ = (int) * out++; - *g++ = (int) * out++; - *b++ = (int) * out++; - } - ok = 1; + opj_image_data_free(inbuf); + opj_image_data_free(outbuf); + } else { /* prec > 8 */ + unsigned short *inbuf, *outbuf, *in, *out; + + max = max_w * max_h; + nr_samples = (size_t)(max * 3U * sizeof(unsigned short)); + in = inbuf = (unsigned short*)opj_image_data_alloc(nr_samples); + out = outbuf = (unsigned short*)opj_image_data_alloc(nr_samples); + + if (inbuf == NULL || outbuf == NULL) { + goto fails1; + } + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + for (i = 0U ; i < max; ++i) { + *in++ = (unsigned short) * r++; + *in++ = (unsigned short) * g++; + *in++ = (unsigned short) * b++; + } + + cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + for (i = 0; i < max; ++i) { + *r++ = (int) * out++; + *g++ = (int) * out++; + *b++ = (int) * out++; + } + ok = 1; fails1: - opj_image_data_free(inbuf); - opj_image_data_free(outbuf); + opj_image_data_free(inbuf); + opj_image_data_free(outbuf); + } + } else { + fprintf(stderr, + "[ERROR] Image components should have the same width and height\n"); + cmsDeleteTransform(transform); + return; } } else { /* image->numcomps <= 2 : GRAY, GRAYA */ if (prec <= 8) { |
