From 75c9fe428fa8ed1dec093de6a7b2dc6ca042f6d6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 20 Apr 2016 10:36:58 +0200 Subject: Update bundled openjpeg from 1.5.0 to 1.5.2 Solves following issues: - Quite reasonable amount of paranoid warnings were solved by an upstream - Upstream seems to have all fixes needed for FreeBSD and OSX already - Brings all fixes and such from upstream --- extern/libopenjpeg/bio.c | 8 +- extern/libopenjpeg/cidx_manager.c | 2 - extern/libopenjpeg/cio.c | 12 +- extern/libopenjpeg/cio.h | 9 +- extern/libopenjpeg/event.c | 9 +- extern/libopenjpeg/image.c | 3 +- extern/libopenjpeg/j2k.c | 207 +++++++++++++++++++++++--- extern/libopenjpeg/jp2.c | 265 ++++++++++++++++++++++++---------- extern/libopenjpeg/openjpeg.h | 4 + extern/libopenjpeg/opj_config.h | 3 +- extern/libopenjpeg/opj_includes.h | 11 +- extern/libopenjpeg/opj_malloc.h | 4 +- extern/libopenjpeg/patches/fbsd.patch | 13 -- extern/libopenjpeg/patches/osx.patch | 17 --- extern/libopenjpeg/t1.c | 1 + extern/libopenjpeg/t2.c | 52 +++++-- extern/libopenjpeg/tcd.c | 119 ++++++++++++--- 17 files changed, 559 insertions(+), 180 deletions(-) delete mode 100644 extern/libopenjpeg/patches/fbsd.patch delete mode 100644 extern/libopenjpeg/patches/osx.patch (limited to 'extern/libopenjpeg') diff --git a/extern/libopenjpeg/bio.c b/extern/libopenjpeg/bio.c index 4c02f464d8d..f04f3e503fb 100644 --- a/extern/libopenjpeg/bio.c +++ b/extern/libopenjpeg/bio.c @@ -42,7 +42,7 @@ Write a bit @param bio BIO handle @param b Bit to write (0 or 1) */ -static void bio_putbit(opj_bio_t *bio, int b); +static void bio_putbit(opj_bio_t *bio, unsigned int b); /** Read a bit @param bio BIO handle @@ -78,7 +78,7 @@ static int bio_byteout(opj_bio_t *bio) { if (bio->bp >= bio->end) { return 1; } - *bio->bp++ = bio->buf >> 8; + *bio->bp++ = (unsigned char)(bio->buf >> 8); return 0; } @@ -92,7 +92,7 @@ static int bio_bytein(opj_bio_t *bio) { return 0; } -static void bio_putbit(opj_bio_t *bio, int b) { +static void bio_putbit(opj_bio_t *bio, unsigned int b) { if (bio->ct == 0) { bio_byteout(bio); } @@ -126,7 +126,7 @@ void bio_destroy(opj_bio_t *bio) { } int bio_numbytes(opj_bio_t *bio) { - return (bio->bp - bio->start); + return (int)(bio->bp - bio->start); } void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { diff --git a/extern/libopenjpeg/cidx_manager.c b/extern/libopenjpeg/cidx_manager.c index 6131b938ea6..f3b251ffa09 100644 --- a/extern/libopenjpeg/cidx_manager.c +++ b/extern/libopenjpeg/cidx_manager.c @@ -29,8 +29,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include "opj_includes.h" diff --git a/extern/libopenjpeg/cio.c b/extern/libopenjpeg/cio.c index b8a7ecf8a87..97cccea6dee 100644 --- a/extern/libopenjpeg/cio.c +++ b/extern/libopenjpeg/cio.c @@ -30,6 +30,7 @@ */ #include "opj_includes.h" +#include /* ----------------------------------------------------------------------- */ @@ -106,6 +107,7 @@ int OPJ_CALLCONV cio_tell(opj_cio_t *cio) { * pos : position, in number of bytes, from the beginning of the stream */ void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) { + assert((cio->start + pos) <= cio->end); cio->bp = cio->start + pos; } @@ -113,6 +115,7 @@ void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) { * Number of bytes left before the end of the stream. */ int cio_numbytesleft(opj_cio_t *cio) { + assert((cio->end - cio->bp) >= 0); return cio->end - cio->bp; } @@ -139,6 +142,7 @@ opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) { * Read a byte. */ unsigned char cio_bytein(opj_cio_t *cio) { + assert(cio->bp >= cio->start); if (cio->bp >= cio->end) { opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end); return 0; @@ -152,7 +156,7 @@ unsigned char cio_bytein(opj_cio_t *cio) { * v : value to write * n : number of bytes to write */ -unsigned int cio_write(opj_cio_t *cio, unsigned long long int v, int n) { +unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) { int i; for (i = n - 1; i >= 0; i--) { if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) ) @@ -173,7 +177,7 @@ unsigned int cio_read(opj_cio_t *cio, int n) { unsigned int v; v = 0; for (i = n - 1; i >= 0; i--) { - v += cio_bytein(cio) << (i << 3); + v += (unsigned int)cio_bytein(cio) << (i << 3); } return v; } @@ -184,6 +188,10 @@ unsigned int cio_read(opj_cio_t *cio, int n) { * n : number of bytes to skip */ void cio_skip(opj_cio_t *cio, int n) { + assert((cio->bp + n) >= cio->bp); + if (((cio->bp + n) < cio->start) || ((cio->bp + n) > cio->end)) { + assert(0); + } cio->bp += n; } diff --git a/extern/libopenjpeg/cio.h b/extern/libopenjpeg/cio.h index ce1a13ecb3a..e62743141ca 100644 --- a/extern/libopenjpeg/cio.h +++ b/extern/libopenjpeg/cio.h @@ -31,6 +31,13 @@ #ifndef __CIO_H #define __CIO_H + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define int64 __int64 +#else +#define int64 long long +#endif + /** @file cio.h @brief Implementation of a byte input-output process (CIO) @@ -63,7 +70,7 @@ Write some bytes @param n Number of bytes to write @return Returns the number of bytes written or 0 if an error occured */ -unsigned int cio_write(opj_cio_t *cio, unsigned long long int v, int n); +unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n); /** Read some bytes @param cio CIO handle diff --git a/extern/libopenjpeg/event.c b/extern/libopenjpeg/event.c index 0dc22f12549..38db33a9432 100644 --- a/extern/libopenjpeg/event.c +++ b/extern/libopenjpeg/event.c @@ -103,18 +103,17 @@ opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, .. va_list arg; int str_length/*, i, j*/; /* UniPG */ char message[MSG_SIZE]; - memset(message, 0, MSG_SIZE); /* initialize the optional parameter list */ va_start(arg, fmt); - /* check the length of the format string */ - str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt); /* parse the format string and put the result in 'message' */ - vsprintf(message, fmt, arg); /* UniPG */ + str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */ /* deinitialize the optional parameter list */ va_end(arg); /* output the message to the user program */ - msg_handler(message, cinfo->client_data); + if( str_length > -1 && str_length < MSG_SIZE ) + msg_handler(message, cinfo->client_data); + else return OPJ_FALSE; } return OPJ_TRUE; diff --git a/extern/libopenjpeg/image.c b/extern/libopenjpeg/image.c index 7c1e7f7faa2..579fd73d718 100644 --- a/extern/libopenjpeg/image.c +++ b/extern/libopenjpeg/image.c @@ -40,7 +40,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c image->color_space = clrspc; image->numcomps = numcmpts; /* allocate memory for the per-component information */ - image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); + image->comps = (opj_image_comp_t*)opj_calloc(1,image->numcomps * sizeof(opj_image_comp_t)); if(!image->comps) { fprintf(stderr,"Unable to allocate memory for image.\n"); opj_image_destroy(image); @@ -86,3 +86,4 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) { opj_free(image); } } + diff --git a/extern/libopenjpeg/j2k.c b/extern/libopenjpeg/j2k.c index d34c75faa7b..93e5c9eb80a 100644 --- a/extern/libopenjpeg/j2k.c +++ b/extern/libopenjpeg/j2k.c @@ -32,6 +32,7 @@ */ #include "opj_includes.h" +#include /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ /*@{*/ @@ -404,6 +405,7 @@ static void j2k_write_siz(opj_j2k_t *j2k) { static void j2k_read_siz(opj_j2k_t *j2k) { int len, i; + int n_comps; opj_cio_t *cio = j2k->cio; opj_image_t *image = j2k->image; @@ -422,12 +424,33 @@ static void j2k_read_siz(opj_j2k_t *j2k) { if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) { opj_event_msg(j2k->cinfo, EVT_ERROR, - "%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n", + "invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n", image->x0,image->x1,image->y0,image->y1); return; } + n_comps = (len - 36 - 2 ) / 3; + assert( (len - 36 - 2 ) % 3 == 0 ); image->numcomps = cio_read(cio, 2); /* Csiz */ + assert( n_comps == image->numcomps ); + (void)n_comps; + + /* testcase 4035.pdf.SIGSEGV.d8b.3375 */ + if (image->x0 > image->x1 || image->y0 > image->y1) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", image->x1 - image->x0, image->y1 - image->y0); + return; + } + /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */ + if (!(cp->tdx * cp->tdy)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy); + return; + } + + /* testcase 1610.pdf.SIGSEGV.59c.681 */ + if (((int64)image->x1) * ((int64)image->y1) != (image->x1 * image->y1)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)\n", image->x1, image->y1); + return; + } #ifdef USE_JPWL if (j2k->cp->correct) { @@ -466,11 +489,19 @@ static void j2k_read_siz(opj_j2k_t *j2k) { /* update components number in the jpwl_exp_comps filed */ cp->exp_comps = image->numcomps; } +#else + (void)len; #endif /* USE_JPWL */ + /* prevent division by zero */ + if (!(cp->tdx * cp->tdy)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy); + return; + } + image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t)); for (i = 0; i < image->numcomps; i++) { - int tmp, w, h; + int tmp; tmp = cio_read(cio, 1); /* Ssiz_i */ image->comps[i].prec = (tmp & 0x7f) + 1; image->comps[i].sgnd = tmp >> 7; @@ -506,9 +537,11 @@ static void j2k_read_siz(opj_j2k_t *j2k) { } #endif /* USE_JPWL */ - /* TODO: unused ? */ - w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); - h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); + /* prevent division by zero */ + if (!(image->comps[i].dx * image->comps[i].dy)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid component size (dx: %d, dy: %d)\n", image->comps[i].dx, image->comps[i].dy); + return; + } image->comps[i].resno_decoded = 0; /* number of resolution decoded */ image->comps[i].factor = cp->reduce; /* reducing factor per component */ @@ -517,6 +550,15 @@ static void j2k_read_siz(opj_j2k_t *j2k) { cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); + /* gdal_fuzzer_check_number_of_tiles.jp2 */ + if (cp->tw == 0 || cp->th == 0 || cp->tw > 65535 / cp->th) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n", + cp->tw, cp->th); + return; + } + + #ifdef USE_JPWL if (j2k->cp->correct) { /* if JPWL is on, we check whether TX errors have damaged @@ -558,7 +600,17 @@ static void j2k_read_siz(opj_j2k_t *j2k) { #endif /* USE_JPWL */ cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); + if (cp->tcps == NULL) + { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n"); + return; + } cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int)); + if (cp->tileno == NULL) + { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n"); + return; + } cp->tileno_size = 0; #ifdef USE_JPWL @@ -684,6 +736,12 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) { "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno); j2k->state |= J2K_STATE_ERR; } + if( tccp->numresolutions > J2K_MAXRLVLS ) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n", + compno, tccp->numresolutions, J2K_MAXRLVLS); + j2k->state |= J2K_STATE_ERR; + tccp->numresolutions = J2K_MAXRLVLS; + } tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ @@ -753,6 +811,7 @@ static void j2k_read_cod(opj_j2k_t *j2k) { opj_image_t *image = j2k->image; len = cio_read(cio, 2); /* Lcod */ + (void)len; tcp->csty = cio_read(cio, 1); /* Scod */ tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* SGcod (A) */ tcp->numlayers = cio_read(cio, 2); /* SGcod (B) */ @@ -806,7 +865,14 @@ static void j2k_read_coc(opj_j2k_t *j2k) { opj_cio_t *cio = j2k->cio; len = cio_read(cio, 2); /* Lcoc */ + (void)len; compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ + if (compno >= image->numcomps) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad component number in COC (%d out of a maximum of %d)\n", + compno, image->numcomps); + return; + } tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ j2k_read_cox(j2k, compno); } @@ -877,6 +943,8 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) { opj_event_msg(j2k->cinfo, EVT_WARNING , "bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n" "- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS); + /* edf_c2_1013627.jp2 */ + numbands = 1; } #endif /* USE_JPWL */ @@ -988,9 +1056,16 @@ static void j2k_read_qcc(opj_j2k_t *j2k) { /* keep your private count of tiles */ backup_compno++; - }; + } #endif /* USE_JPWL */ + if ((compno < 0) || (compno >= numcomp)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad component number in QCC (%d out of a maximum of %d)\n", + compno, j2k->image->numcomps); + return; + } + j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); } @@ -1036,6 +1111,15 @@ static void j2k_read_poc(opj_j2k_t *j2k) { len = cio_read(cio, 2); /* Lpoc */ numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2)); + if( numpchgs >= 32 ) + { + /* edf_c2_1103421.jp2 */ + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad number of POCS (%d out of a maximum of %d)\n", + numpchgs, 32); + numpchgs = 0; + } + for (i = old_poc; i < numpchgs + old_poc; i++) { opj_poc_t *poc; poc = &tcp->pocs[i]; @@ -1058,9 +1142,12 @@ static void j2k_read_crg(opj_j2k_t *j2k) { int numcomps = j2k->image->numcomps; len = cio_read(cio, 2); /* Lcrg */ + (void)len; for (i = 0; i < numcomps; i++) { Xcrg_i = cio_read(cio, 2); /* Xcrg_i */ + (void)Xcrg_i; Ycrg_i = cio_read(cio, 2); /* Ycrg_i */ + (void)Ycrg_i; } } @@ -1072,13 +1159,16 @@ static void j2k_read_tlm(opj_j2k_t *j2k) { len = cio_read(cio, 2); /* Ltlm */ Ztlm = cio_read(cio, 1); /* Ztlm */ + (void)Ztlm; Stlm = cio_read(cio, 1); /* Stlm */ ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); SP = (Stlm >> 6) & 0x01; tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); for (i = 0; i < tile_tlm; i++) { Ttlm_i = cio_read(cio, ST); /* Ttlm_i */ + (void)Ttlm_i; Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */ + (void)Ptlm_i; } } @@ -1089,6 +1179,7 @@ static void j2k_read_plm(opj_j2k_t *j2k) { len = cio_read(cio, 2); /* Lplm */ Zplm = cio_read(cio, 1); /* Zplm */ + (void)Zplm; len -= 3; while (len > 0) { Nplm = cio_read(cio, 4); /* Nplm */ @@ -1114,6 +1205,7 @@ static void j2k_read_plt(opj_j2k_t *j2k) { len = cio_read(cio, 2); /* Lplt */ Zplt = cio_read(cio, 1); /* Zplt */ + (void)Zplt; for (i = len - 3; i > 0; i--) { add = cio_read(cio, 1); packet_len = (packet_len << 7) + add; /* Iplt_i */ @@ -1261,6 +1353,7 @@ static void j2k_read_sot(opj_j2k_t *j2k) { opj_cio_t *cio = j2k->cio; len = cio_read(cio, 2); + (void)len; tileno = cio_read(cio, 2); #ifdef USE_JPWL @@ -1269,7 +1362,7 @@ static void j2k_read_sot(opj_j2k_t *j2k) { static int backup_tileno = 0; /* tileno is negative or larger than the number of tiles!!! */ - if ((tileno < 0) || (tileno > (cp->tw * cp->th))) { + if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) { opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: bad tile number (%d out of a maximum of %d)\n", tileno, (cp->tw * cp->th)); @@ -1286,8 +1379,18 @@ static void j2k_read_sot(opj_j2k_t *j2k) { /* keep your private count of tiles */ backup_tileno++; - }; + } + else #endif /* USE_JPWL */ + { + /* tileno is negative or larger than the number of tiles!!! */ + if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad tile number (%d out of a maximum of %d)\n", + tileno, (cp->tw * cp->th)); + return; + } + } if (cp->tileno_size == 0) { cp->tileno[cp->tileno_size] = tileno; @@ -1325,8 +1428,18 @@ static void j2k_read_sot(opj_j2k_t *j2k) { totlen); } - }; + } + else #endif /* USE_JPWL */ + { + /* totlen is negative or larger than the bytes left!!! */ + if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad tile byte size (%d bytes against %d bytes left)\n", + totlen, cio_numbytesleft(cio) + 8); + return; + } + } if (!totlen) totlen = cio_numbytesleft(cio) + 8; @@ -1478,7 +1591,13 @@ static void j2k_read_sod(opj_j2k_t *j2k) { } data = j2k->tile_data[curtileno]; + data_ptr = data; /* store in case of failure */ data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); + if( data == NULL ) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not reallocated\n" ); + opj_free( data_ptr ); + return; + } data_ptr = data + j2k->tile_len[curtileno]; for (i = 0; i < len; i++) { @@ -1518,8 +1637,10 @@ static void j2k_read_rgn(opj_j2k_t *j2k) { int numcomps = j2k->image->numcomps; len = cio_read(cio, 2); /* Lrgn */ + (void)len; compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ roisty = cio_read(cio, 1); /* Srgn */ + (void)roisty; #ifdef USE_JPWL if (j2k->cp->correct) { @@ -1536,6 +1657,13 @@ static void j2k_read_rgn(opj_j2k_t *j2k) { }; #endif /* USE_JPWL */ + if (compno >= numcomps) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad component number in RGN (%d out of a maximum of %d)\n", + compno, j2k->image->numcomps); + return; + } + tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ } @@ -1554,7 +1682,7 @@ static void j2k_write_eoc(opj_j2k_t *j2k) { static void j2k_read_eoc(opj_j2k_t *j2k) { int i, tileno; - opj_bool success; + opj_bool success = OPJ_FALSE; /* if packets should be decoded */ if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) { @@ -1562,11 +1690,17 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { tcd_malloc_decode(tcd, j2k->image, j2k->cp); for (i = 0; i < j2k->cp->tileno_size; i++) { tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); - tileno = j2k->cp->tileno[i]; - success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); - opj_free(j2k->tile_data[tileno]); - j2k->tile_data[tileno] = NULL; - tcd_free_decode_tile(tcd, i); + if (j2k->cp->tileno[i] != -1) + { + tileno = j2k->cp->tileno[i]; + success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); + assert( tileno != -1 ); + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + tcd_free_decode_tile(tcd, i); + } + else + success = OPJ_FALSE; if (success == OPJ_FALSE) { j2k->state |= J2K_STATE_ERR; break; @@ -1737,6 +1871,17 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) { opj_free(j2k->tile_len); } if(j2k->tile_data != NULL) { + if(j2k->cp != NULL) { + for (i = 0; i < j2k->cp->tileno_size; i++) { + int tileno = j2k->cp->tileno[i]; + if( tileno != -1 ) + { + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + } + } + } + opj_free(j2k->tile_data); } if(j2k->default_tcp != NULL) { @@ -1856,9 +2001,15 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c #endif /* USE_JPWL */ if (id >> 8 != 0xff) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); - return 0; + if(cio_numbytesleft(cio) != 0) /* not end of file reached and no EOC */ + { + opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + opj_image_destroy(image); + return 0; + } + opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + j2k->state = J2K_STATE_NEOC; + break; } e = j2k_dec_mstab_lookup(id); /* Check if the marker is known*/ @@ -1877,7 +2028,10 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c (*e->handler)(j2k); } if (j2k->state & J2K_STATE_ERR) + { + opj_image_destroy(image); return NULL; + } if (j2k->state == J2K_STATE_MT) { break; @@ -1888,6 +2042,11 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c } if (j2k->state == J2K_STATE_NEOC) { j2k_read_eoc(j2k); + /* Check one last time for errors during decoding before returning */ + if (j2k->state & J2K_STATE_ERR) { + opj_image_destroy(image); + return NULL; + } } if (j2k->state != J2K_STATE_MT) { @@ -1949,9 +2108,15 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre id = cio_read(cio, 2); if (id >> 8 != 0xff) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); - return 0; + if(cio_numbytesleft(cio) != 0) /* no end of file reached and no EOC */ + { + opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + opj_image_destroy(image); + return 0; + } + opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + j2k->state = J2K_STATE_NEOC; + break; } e = j2k_dec_mstab_lookup(id); if (!(j2k->state & e->states)) { diff --git a/extern/libopenjpeg/jp2.c b/extern/libopenjpeg/jp2.c index 5ae114c33b9..d3322603c8b 100644 --- a/extern/libopenjpeg/jp2.c +++ b/extern/libopenjpeg/jp2.c @@ -30,6 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include "opj_includes.h" +#include /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ /*@{*/ @@ -172,6 +173,9 @@ static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_bo } else if (box->length == 0) { box->length = cio_numbytesleft(cio) + 8; + } else if (box->length < 0) { + opj_event_msg(cinfo, EVT_ERROR, "Integer overflow in box->length\n"); + return OPJ_FALSE; /* TODO: actually check jp2_read_boxhdr's return value */ } return OPJ_TRUE; @@ -206,7 +210,10 @@ static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if(jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_IHDR != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n"); return OPJ_FALSE; @@ -279,7 +286,10 @@ static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_BPCC != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n"); return OPJ_FALSE; @@ -469,7 +479,7 @@ static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio, for(i = 0; i < nr_channels; ++i) { /* Cji */ - *entries++ = cio_read(cio, channel_size[i]>>3); + *entries++ = cio_read(cio, (channel_size[i]+7)>>3); } } @@ -512,10 +522,8 @@ static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio, static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) { opj_jp2_cdef_info_t *info; - int color_space; unsigned short i, n, cn, typ, asoc, acn; - color_space = image->color_space; info = color->jp2_cdef->info; n = color->jp2_cdef->n; @@ -525,6 +533,7 @@ static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) if((asoc = info[i].asoc) == 0) continue; cn = info[i].cn; typ = info[i].typ; acn = asoc - 1; + (void)typ; if(cn != acn) { @@ -639,90 +648,173 @@ opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color) opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); - do - { - if (JP2_JP2H != box.type) - { - if (box.type == JP2_JP2C) - { - opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); - return OPJ_FALSE; - } - cio_skip(cio, box.length - 8); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + do { + if (JP2_JP2H != box.type) + { + if (box.type == JP2_JP2C) + { + opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); + return OPJ_FALSE; + } + if (box.length <= 8) return OPJ_FALSE; + cio_skip(cio, box.length - 8); - if(cio->bp >= cio->end) return OPJ_FALSE; + if(cio->bp >= cio->end) return OPJ_FALSE; - jp2_read_boxhdr(cinfo, cio, &box); - } - } while(JP2_JP2H != box.type); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + } + } while(JP2_JP2H != box.type); if (!jp2_read_ihdr(jp2, cio)) return OPJ_FALSE; jp2h_end = box.init_pos + box.length; - if (jp2->bpc == 255) - { - if (!jp2_read_bpcc(jp2, cio)) - return OPJ_FALSE; - } - jp2_read_boxhdr(cinfo, cio, &box); + if (jp2->bpc == 255) + { + if (!jp2_read_bpcc(jp2, cio)) + return OPJ_FALSE; + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; - while(cio_tell(cio) < jp2h_end) - { - if(box.type == JP2_COLR) - { - if( !jp2_read_colr(jp2, cio, &box, color)) - { - cio_seek(cio, box.init_pos + 8); - cio_skip(cio, box.length - 8); - } - jp2_read_boxhdr(cinfo, cio, &box); - continue; - } + while(cio_tell(cio) < jp2h_end) + { + if(box.type == JP2_COLR) + { + if( !jp2_read_colr(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef) - { - if( !jp2_read_cdef(jp2, cio, &box, color)) - { - cio_seek(cio, box.init_pos + 8); - cio_skip(cio, box.length - 8); - } - jp2_read_boxhdr(cinfo, cio, &box); - continue; - } + { + if( !jp2_read_cdef(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef) - { - if( !jp2_read_pclr(jp2, cio, &box, color)) - { - cio_seek(cio, box.init_pos + 8); - cio_skip(cio, box.length - 8); - } - jp2_read_boxhdr(cinfo, cio, &box); - continue; - } + { + if( !jp2_read_pclr(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef) - { - if( !jp2_read_cmap(jp2, cio, &box, color)) - { + { + if( !jp2_read_cmap(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } + if (box.length <= 8) return OPJ_FALSE; cio_seek(cio, box.init_pos + 8); cio_skip(cio, box.length - 8); - } - jp2_read_boxhdr(cinfo, cio, &box); - continue; - } - cio_seek(cio, box.init_pos + 8); - cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; - }/* while(cio_tell(cio) < box_end) */ + }/* while(cio_tell(cio) < box_end) */ - cio_seek(cio, jp2h_end); + cio_seek(cio, jp2h_end); -/* Part 1, I.5.3.3 : 'must contain at least one' */ - return (color->jp2_has_colr == 1); + /* Part 1, I.5.3.3 : 'must contain at least one' */ + return (color->jp2_has_colr == 1); }/* jp2_read_jp2h() */ +static opj_bool opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_common_ptr cinfo) +{ + int i; + + /* testcase 4149.pdf.SIGSEGV.cf7.3501 */ + if (color->jp2_cdef) { + opj_jp2_cdef_info_t *info = color->jp2_cdef->info; + int n = color->jp2_cdef->n; + + for (i = 0; i < n; i++) { + if (info[i].cn >= image->numcomps) { + opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps); + return OPJ_FALSE; + } + if (info[i].asoc > 0 && (info[i].asoc - 1) >= image->numcomps) { + opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps); + return OPJ_FALSE; + } + } + } + + /* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and + 66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */ + if (color->jp2_pclr && color->jp2_pclr->cmap) { + int nr_channels = color->jp2_pclr->nr_channels; + opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap; + opj_bool *pcol_usage, is_sane = OPJ_TRUE; + + /* verify that all original components match an existing one */ + for (i = 0; i < nr_channels; i++) { + if (cmap[i].cmp >= image->numcomps) { + opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps); + is_sane = OPJ_FALSE; + } + } + + pcol_usage = opj_calloc(nr_channels, sizeof(opj_bool)); + if (!pcol_usage) { + opj_event_msg(cinfo, EVT_ERROR, "Unexpected OOM.\n"); + return OPJ_FALSE; + } + /* verify that no component is targeted more than once */ + for (i = 0; i < nr_channels; i++) { + int pcol = cmap[i].pcol; + assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1); + if (pcol >= nr_channels) { + opj_event_msg(cinfo, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol); + is_sane = OPJ_FALSE; + } + else if (pcol_usage[pcol] && cmap[i].mtyp == 1) { + opj_event_msg(cinfo, EVT_ERROR, "Component %d is mapped twice.\n", pcol); + is_sane = OPJ_FALSE; + } + else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) { + /* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then + * the value of this field shall be 0. */ + opj_event_msg(cinfo, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol); + is_sane = OPJ_FALSE; + } + else + pcol_usage[pcol] = OPJ_TRUE; + } + /* verify that all components are targeted at least once */ + for (i = 0; i < nr_channels; i++) { + if (!pcol_usage[i] && cmap[i].mtyp != 0) { + opj_event_msg(cinfo, EVT_ERROR, "Component %d doesn't have a mapping.\n", i); + is_sane = OPJ_FALSE; + } + } + opj_free(pcol_usage); + if (!is_sane) { + return OPJ_FALSE; + } + } + + return OPJ_TRUE; +} + opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { @@ -756,6 +848,10 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, } if (!jp2->ignore_pclr_cmap_cdef){ + if (!opj_jp2_check_color(image, &color, cinfo)) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to decode PCRL box\n"); + return NULL; + } /* Set Image Color Space */ if (jp2->enumcs == 16) @@ -839,8 +935,10 @@ static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); - + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_FTYP != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n"); return OPJ_FALSE; @@ -849,6 +947,14 @@ static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { jp2->brand = cio_read(cio, 4); /* BR */ jp2->minversion = cio_read(cio, 4); /* MinV */ jp2->numcl = (box.length - 16) / 4; + + /* edf_c2_1673169.jp2 */ + if (cio_numbytesleft(cio) < ((int)jp2->numcl * 4)) { + opj_event_msg(cinfo, EVT_ERROR, "Not enough bytes in FTYP Box " + "(expected %d, but only %d left)\n", + ((int)jp2->numcl * 4), cio_numbytesleft(cio)); + return OPJ_FALSE; + } jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int)); for (i = 0; i < (int)jp2->numcl; i++) { @@ -897,15 +1003,20 @@ static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_ opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } do { if(JP2_JP2C != box.type) { + if (box.length <= 8) return OPJ_FALSE; cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; } } while(JP2_JP2C != box.type); *j2k_codestream_offset = cio_tell(cio); + if (box.length <= 8) return OPJ_FALSE; *j2k_codestream_length = box.length - 8; return OPJ_TRUE; @@ -930,7 +1041,10 @@ static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_JP != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n"); return OPJ_FALSE; @@ -1070,6 +1184,7 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) { opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) { opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t)); if(jp2) { + memset(jp2, 0, sizeof(opj_jp2_t)); jp2->cinfo = cinfo; /* create the J2K codec */ jp2->j2k = j2k_create_compress(cinfo); diff --git a/extern/libopenjpeg/openjpeg.h b/extern/libopenjpeg/openjpeg.h index 53e9fac0438..59147c8b3d1 100644 --- a/extern/libopenjpeg/openjpeg.h +++ b/extern/libopenjpeg/openjpeg.h @@ -135,6 +135,10 @@ typedef enum COLOR_SPACE { CLRSPC_SYCC = 3 /**< YUV */ } OPJ_COLOR_SPACE; +#define ENUMCS_SRGB 16 +#define ENUMCS_GRAY 17 +#define ENUMCS_SYCC 18 + /** Supported codec */ diff --git a/extern/libopenjpeg/opj_config.h b/extern/libopenjpeg/opj_config.h index 82e12be03a9..5d0a877b840 100644 --- a/extern/libopenjpeg/opj_config.h +++ b/extern/libopenjpeg/opj_config.h @@ -3,7 +3,7 @@ * the endian check is a blender define */ /* create config.h for CMake */ -#define PACKAGE_VERSION "1.5.0" +#define PACKAGE_VERSION "1.5.2" #define HAVE_INTTYPES_H #define HAVE_MEMORY_H @@ -23,6 +23,7 @@ /* #undef HAVE_LIBLCMS2 */ /* #undef HAVE_LCMS1_H */ /* #undef HAVE_LCMS2_H */ +/* #undef USE_SYSTEM_GETOPT */ /* Byte order. */ /* All compilers that support Mac OS X define either __BIG_ENDIAN__ or diff --git a/extern/libopenjpeg/opj_includes.h b/extern/libopenjpeg/opj_includes.h index 2b5866a9990..e9194fd9886 100644 --- a/extern/libopenjpeg/opj_includes.h +++ b/extern/libopenjpeg/opj_includes.h @@ -89,18 +89,17 @@ Most compilers implement their own version of this keyword ... /* MSVC and Borland C do not have lrintf */ #if defined(_MSC_VER) || defined(__BORLANDC__) static INLINE long lrintf(float f){ -#ifdef _M_X64 - return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); -#else - int i; +#ifdef _M_IX86 + long int i; _asm{ fld f fistp i }; - return i; -#endif +#else + return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); +#endif /* _M_IX86 */ } #endif diff --git a/extern/libopenjpeg/opj_malloc.h b/extern/libopenjpeg/opj_malloc.h index 87493f497c7..aef2ee3b8c9 100644 --- a/extern/libopenjpeg/opj_malloc.h +++ b/extern/libopenjpeg/opj_malloc.h @@ -83,8 +83,10 @@ Allocate memory aligned to a 16 byte boundry #else /* Not _WIN32 */ #if defined(__sun) #define HAVE_MEMALIGN + #elif defined(__FreeBSD__) + #define HAVE_POSIX_MEMALIGN /* Linux x86_64 and OSX always align allocations to 16 bytes */ - #elif !defined(__amd64__) && !defined(__APPLE__) + #elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX) #define HAVE_MEMALIGN #include #endif diff --git a/extern/libopenjpeg/patches/fbsd.patch b/extern/libopenjpeg/patches/fbsd.patch deleted file mode 100644 index 90e77600941..00000000000 --- a/extern/libopenjpeg/patches/fbsd.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: extern/libopenjpeg/opj_malloc.h -=================================================================== ---- extern/libopenjpeg/opj_malloc.h (revision 27736) -+++ extern/libopenjpeg/opj_malloc.h (working copy) -@@ -76,7 +76,7 @@ - #if defined(__sun) - #define HAVE_MEMALIGN - #elif defined(__GNUC__) -- #ifndef __APPLE__ -+ #if !defined(__APPLE__) && !defined(__FreeBSD__) - #define HAVE_MEMALIGN - #include - #endif diff --git a/extern/libopenjpeg/patches/osx.patch b/extern/libopenjpeg/patches/osx.patch deleted file mode 100644 index c518978eed6..00000000000 --- a/extern/libopenjpeg/patches/osx.patch +++ /dev/null @@ -1,17 +0,0 @@ -Index: opj_malloc.h -=================================================================== ---- opj_malloc.h (revision 15089) -+++ opj_malloc.h (working copy) -@@ -76,8 +76,10 @@ - #if defined(__sun) - #define HAVE_MEMALIGN - #elif defined(__GNUC__) -- #define HAVE_MEMALIGN -- #include -+ #ifndef __APPLE__ -+ #define HAVE_MEMALIGN -+ #include -+ #endif - /* Linux x86_64 and OSX always align allocations to 16 bytes */ - #elif !defined(__amd64__) && !defined(__APPLE__) - /* FIXME: Yes, this is a big assumption */ diff --git a/extern/libopenjpeg/t1.c b/extern/libopenjpeg/t1.c index 477720412aa..ed9cdc3fea6 100644 --- a/extern/libopenjpeg/t1.c +++ b/extern/libopenjpeg/t1.c @@ -1577,6 +1577,7 @@ void t1_decode_cblks( opj_free(cblk->segs); } /* cblkno */ opj_free(precinct->cblks.dec); + precinct->cblks.dec = NULL; } /* precno */ } /* bandno */ } /* resno */ diff --git a/extern/libopenjpeg/t2.c b/extern/libopenjpeg/t2.c index 232a5437329..2585c3d56a6 100644 --- a/extern/libopenjpeg/t2.c +++ b/extern/libopenjpeg/t2.c @@ -30,6 +30,7 @@ */ #include "opj_includes.h" +#include /** @defgroup T2 T2 - Implementation of a tier-2 coding */ /*@{*/ @@ -64,7 +65,7 @@ static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterato @param cblksty @param first */ -static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first); +static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first); /** Decode a packet of a tile from a source buffer @param t2 T2 handle @@ -296,9 +297,17 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera return (c - dest); } -static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) { +static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) { opj_tcd_seg_t* seg; - cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t)); + opj_tcd_seg_t* segs; + segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t)); + + if (segs == NULL) + { + return OPJ_FALSE; + } + cblk->segs = segs; + seg = &cblk->segs[index]; seg->data = NULL; seg->dataindex = 0; @@ -316,6 +325,8 @@ static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int fi } else { seg->maxpasses = 109; } + + return OPJ_TRUE; } static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, @@ -330,13 +341,15 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t int precno = pi->precno; /* precinct value */ int layno = pi->layno; /* quality layer value */ - opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno]; - unsigned char *hd = NULL; int present; opj_bio_t *bio = NULL; /* BIO component */ - + + opj_tcd_resolution_t* res; + assert(&tile->comps[compno] != NULL); + res = &tile->comps[compno].resolutions[resno]; + if (layno == 0) { for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; @@ -462,12 +475,22 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t cblk->numlenbits += increment; segno = 0; if (!cblk->numsegs) { - t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1); + if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1)) + { + opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n"); + bio_destroy(bio); + return -999; + } } else { segno = cblk->numsegs - 1; if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) { ++segno; - t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); + if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0)) + { + opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n"); + bio_destroy(bio); + return -999; + } } } n = cblk->numnewpasses; @@ -478,7 +501,12 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t n -= cblk->segs[segno].numnewpasses; if (n > 0) { ++segno; - t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); + if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0)) + { + opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n"); + bio_destroy(bio); + return -999; + } } } while (n > 0); } @@ -714,7 +742,11 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj } else { e = 0; } - if(e == -999) return -999; + if(e == -999) + { + pi_destroy(pi, cp, tileno); + return -999; + } /* progression in resolution */ image->comps[pi[pino].compno].resno_decoded = (e > 0) ? diff --git a/extern/libopenjpeg/tcd.c b/extern/libopenjpeg/tcd.c index 18cdbc786bc..62904eb2c65 100644 --- a/extern/libopenjpeg/tcd.c +++ b/extern/libopenjpeg/tcd.c @@ -30,7 +30,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#define _ISOC99_SOURCE /* lrintf is C99 */ #include "opj_includes.h" +#include void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) { int tileno, compno, resno, bandno, precno;/*, cblkno;*/ @@ -249,7 +251,9 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c cbgwidthexpn = pdx - 1; cbgheightexpn = pdy - 1; } - + (void)brcbgyend; + (void)brcbgxend; + cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); @@ -333,8 +337,10 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c cblk->y0 = int_max(cblkystart, prc->y0); cblk->x1 = int_min(cblkxend, prc->x1); cblk->y1 = int_min(cblkyend, prc->y1); - cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char)); + cblk->data = (unsigned char*) opj_calloc(9728+2, sizeof(unsigned char)); /* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */ + cblk->data[0] = 0; + cblk->data[1] = 0; cblk->data += 2; cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t)); cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t)); @@ -509,6 +515,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur cbgwidthexpn = pdx - 1; cbgheightexpn = pdy - 1; } + (void)brcbgyend; + (void)brcbgxend; cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); @@ -594,6 +602,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur cblk->y1 = int_min(cblkyend, prc->y1); cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char)); /* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */ + cblk->data[0] = 0; + cblk->data[1] = 0; cblk->data += 2; cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t)); cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t)); @@ -614,7 +624,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { tcd->image = image; tcd->tcd_image->tw = cp->tw; tcd->tcd_image->th = cp->th; - tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t)); + tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(cp->tw * cp->th, sizeof(opj_tcd_tile_t)); /* Allocate place to store the decoded data = final image @@ -690,6 +700,12 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, opj_tccp_t *tccp = &tcp->tccps[compno]; opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tccp->numresolutions <= 0) + { + cp->tileno[tileno] = -1; + return; + } + /* border of each tile component (global) */ tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); @@ -749,6 +765,8 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, cbgwidthexpn = pdx - 1; cbgheightexpn = pdy - 1; } + (void)brcbgyend; + (void)brcbgxend; cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); @@ -1370,16 +1388,31 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno if (l == -999) { eof = 1; opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: incomplete bistream\n"); + return OPJ_FALSE; } /*------------------TIER1-----------------*/ t1_time = opj_clock(); /* time needed to decode a tile */ t1 = t1_create(tcd->cinfo); + if (t1 == NULL) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n"); + t1_destroy(t1); + return OPJ_FALSE; + } + for (compno = 0; compno < tile->numcomps; ++compno) { opj_tcd_tilecomp_t* tilec = &tile->comps[compno]; /* The +3 is headroom required by the vectorized DWT */ tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int)); + if (tilec->data == NULL) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n"); + t1_destroy(t1); + return OPJ_FALSE; + } + t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]); } t1_destroy(t1); @@ -1394,13 +1427,15 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno int numres2decode; if (tcd->cp->reduce != 0) { - tcd->image->comps[compno].resno_decoded = - tile->comps[compno].numresolutions - tcd->cp->reduce - 1; - if (tcd->image->comps[compno].resno_decoded < 0) { + if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) { opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number " " of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions); return OPJ_FALSE; } + else { + tcd->image->comps[compno].resno_decoded = + tile->comps[compno].numresolutions - tcd->cp->reduce - 1; + } } numres2decode = tcd->image->comps[compno].resno_decoded + 1; @@ -1421,6 +1456,13 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0); if (tile->numcomps >= 3 ){ + /* testcase 1336.pdf.asan.47.376 */ + if ((tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) < n || + ( tile->comps[1].x1 - tile->comps[1].x0) * (tile->comps[1].y1 - tile->comps[1].y0) < n || + ( tile->comps[2].x1 - tile->comps[2].x0) * (tile->comps[2].y1 - tile->comps[2].y0) < n) { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Tiles don't all have the same dimension. Skip the MCT step.\n"); + return OPJ_FALSE; + } if (tcd->tcp->tccps[0].qmfbid == 1) { mct_decode( tile->comps[0].data, @@ -1452,18 +1494,33 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno int tw = tilec->x1 - tilec->x0; int w = imagec->w; + int i, j; int offset_x = int_ceildivpow2(imagec->x0, imagec->factor); int offset_y = int_ceildivpow2(imagec->y0, imagec->factor); + /* NR-DEC-2977.pdf.asan.67.2198.jp2-52-decode */ + if( res->x0 - offset_x < 0 || res->x1 - offset_x < 0 + || res->y0 - offset_y < 0 || res->y1 - offset_y < 0 ) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Impossible offsets %d / %d\n", offset_x, offset_y); + return OPJ_FALSE; + } + assert( 0 <= res->x0 - offset_x && 0 <= res->x1 - offset_x ); + assert( 0 <= res->y0 - offset_y && 0 <= res->y1 - offset_y ); - int i, j; if(!imagec->data){ imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int)); } + if (!imagec->data) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n"); + return OPJ_FALSE; + } if(tcd->tcp->tccps[compno].qmfbid == 1) { for(j = res->y0; j < res->y1; ++j) { for(i = res->x0; i < res->x1; ++i) { int v = tilec->data[i - res->x0 + (j - res->y0) * tw]; v += adjust; + /*assert( (i - offset_x) + (j - offset_y) * w >= 0 );*/ imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); } } @@ -1473,6 +1530,7 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw]; int v = lrintf(tmp); v += adjust; + /*assert( (i - offset_x) + (j - offset_y) * w >= 0 );*/ imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); } } @@ -1492,32 +1550,51 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno void tcd_free_decode(opj_tcd_t *tcd) { opj_tcd_image_t *tcd_image = tcd->tcd_image; + int i = 0; + for (i = 0; i < tcd_image->tw * tcd_image->th; i++) + { + tcd_free_decode_tile(tcd, i); + } + opj_free(tcd_image->tiles); } void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) { - int compno,resno,bandno,precno; + int compno,resno,bandno,precno,cblkno; opj_tcd_image_t *tcd_image = tcd->tcd_image; opj_tcd_tile_t *tile = &tcd_image->tiles[tileno]; - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - for (resno = 0; resno < tilec->numresolutions; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->ph * res->pw; precno++) { - opj_tcd_precinct_t *prec = &band->precincts[precno]; - if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); - if (prec->incltree != NULL) tgt_destroy(prec->incltree); + if (tile->comps != NULL) { + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->ph * res->pw; precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + if (prec->cblks.dec != NULL) { + for (cblkno = 0; cblkno < prec->cw * prec->ch; ++cblkno) { + opj_tcd_cblk_dec_t* cblk = &prec->cblks.dec[cblkno]; + opj_free(cblk->data); + opj_free(cblk->segs); + } + opj_free(prec->cblks.dec); + } + if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); + if (prec->incltree != NULL) tgt_destroy(prec->incltree); + + + } + opj_free(band->precincts); } - opj_free(band->precincts); } + opj_free(tilec->resolutions); } - opj_free(tilec->resolutions); + opj_free(tile->comps); + tile->comps = NULL; } - opj_free(tile->comps); } -- cgit v1.2.3