X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fjpeg2000dec.c;h=96dab8e1766c1675a89782c48c54418efc96e807;hb=ee1e3ca5eb1ec7d34e925d129c893e33847ee0b7;hp=5414ce565547c0f4f0a68dc00075672621c91bde;hpb=75bf51ef87f4cb5afca701b33bf22339d8a4db24;p=ffmpeg diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 5414ce56554..96dab8e1766 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -82,7 +82,7 @@ typedef struct Jpeg2000Tile { Jpeg2000CodingStyle codsty[4]; Jpeg2000QuantStyle qntsty[4]; Jpeg2000POC poc; - Jpeg2000TilePart tile_part[256]; + Jpeg2000TilePart tile_part[32]; uint16_t tp_idx; // Tile-part index int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} } Jpeg2000Tile; @@ -343,7 +343,10 @@ static int get_siz(Jpeg2000DecoderContext *s) s->numXtiles = ff_jpeg2000_ceildiv(s->width - s->tile_offset_x, s->tile_width); s->numYtiles = ff_jpeg2000_ceildiv(s->height - s->tile_offset_y, s->tile_height); - if (s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(*s->tile)) { + // There must be at least a SOT and SOD per tile, their minimum size is 14 + if (s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(*s->tile) || + s->numXtiles * s->numYtiles * 14LL > bytestream2_size(&s->g) + ) { s->numXtiles = s->numYtiles = 0; return AVERROR(EINVAL); } @@ -761,7 +764,10 @@ static int get_sot(Jpeg2000DecoderContext *s, int n) return AVERROR_INVALIDDATA; } - av_assert0(TPsot < FF_ARRAY_ELEMS(s->tile[Isot].tile_part)); + if (TPsot >= FF_ARRAY_ELEMS(s->tile[Isot].tile_part)) { + avpriv_request_sample(s->avctx, "Too many tile parts"); + return AVERROR_PATCHWELCOME; + } s->tile[Isot].tp_idx = TPsot; tp = s->tile[Isot].tile_part + TPsot; @@ -1156,6 +1162,9 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2 step_x = 32; step_y = 32; + if (RSpoc > FFMIN(codsty->nreslevels, REpoc)) + continue; + for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) { uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; @@ -1175,10 +1184,10 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2 int xc = x / s->cdx[compno]; int yc = y / s->cdy[compno]; - if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check + if (yc % (1LL << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check continue; - if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check + if (xc % (1LL << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check continue; // check if a precinct exists @@ -1245,10 +1254,10 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2 if (reslevelno >= codsty->nreslevels) continue; - if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check + if (yc % (1LL << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check continue; - if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check + if (xc % (1LL << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check continue; // check if a precinct exists @@ -1316,10 +1325,10 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2 uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; - if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check + if (yc % (1LL << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check continue; - if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check + if (xc % (1LL << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check continue; // check if a precinct exists @@ -2047,7 +2056,6 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) } } else if (atom2 == MKBETAG('p','c','l','r') && atom2_size >= 6) { int i, size, colour_count, colour_channels, colour_depth[3]; - uint32_t r, g, b; colour_count = bytestream2_get_be16u(&s->g); colour_channels = bytestream2_get_byteu(&s->g); // FIXME: Do not ignore channel_sign @@ -2057,7 +2065,7 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) size = (colour_depth[0] + 7 >> 3) * colour_count + (colour_depth[1] + 7 >> 3) * colour_count + (colour_depth[2] + 7 >> 3) * colour_count; - if (colour_count > 256 || + if (colour_count > AVPALETTE_COUNT || colour_channels != 3 || colour_depth[0] > 16 || colour_depth[1] > 16 || @@ -2069,6 +2077,7 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) } s->pal8 = 1; for (i = 0; i < colour_count; i++) { + uint32_t r, g, b; if (colour_depth[0] <= 8) { r = bytestream2_get_byteu(&s->g) << 8 - colour_depth[0]; r |= r >> colour_depth[0];