X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fj2kdec.c;h=2cbd7cc529aea902170de922087bb6fee82a9ba7;hb=bd36ec55bef7c446079e192655d065fd86483876;hp=1f4acc53fdd183ee53e64ba82eadea190cb97c3f;hpb=92afb431621c79155fcb7171d26f137eb1bee028;p=ffmpeg diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c index 1f4acc53fdd..2cbd7cc529a 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -220,6 +220,9 @@ static int get_siz(J2kDecoderContext *s) s->tile_offset_y = bytestream_get_be32(&s->buf); // YT0Siz s->ncomponents = bytestream_get_be16(&s->buf); // CSiz + if(s->tile_width<=0 || s->tile_height<=0) + return AVERROR(EINVAL); + if (s->buf_end - s->buf < 2 * s->ncomponents) return AVERROR(EINVAL); @@ -235,6 +238,9 @@ static int get_siz(J2kDecoderContext *s) s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width); s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height); + if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile)) + return AVERROR(EINVAL); + s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile)); if (!s->tile) return AVERROR(ENOMEM); @@ -268,7 +274,7 @@ static int get_siz(J2kDecoderContext *s) if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) return ret; - s->picture.pict_type = FF_I_TYPE; + s->picture.pict_type = AV_PICTURE_TYPE_I; s->picture.key_frame = 1; return 0; @@ -359,7 +365,7 @@ static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q) if (q->quantsty == J2K_QSTY_NONE){ n -= 3; - if (s->buf_end - s->buf < n) + if (s->buf_end - s->buf < n || 32*3 < n) return AVERROR(EINVAL); for (i = 0; i < n; i++) q->expn[i] = bytestream_get_byte(&s->buf) >> 3; @@ -376,7 +382,7 @@ static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q) } } else{ n = (n - 3) >> 1; - if (s->buf_end - s->buf < n) + if (s->buf_end - s->buf < n || 32*3 < n) return AVERROR(EINVAL); for (i = 0; i < n; i++){ x = bytestream_get_be16(&s->buf); @@ -421,6 +427,10 @@ static uint8_t get_sot(J2kDecoderContext *s) return AVERROR(EINVAL); s->curtileno = bytestream_get_be16(&s->buf); ///< Isot + if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){ + s->curtileno=0; + return AVERROR(EINVAL); + } s->buf += 4; ///< Psot (ignored) @@ -911,7 +921,7 @@ static int decode_codestream(J2kDecoderContext *s) marker = bytestream_get_be16(&s->buf); if(s->avctx->debug & FF_DEBUG_STARTCODE) - av_log(s->avctx, AV_LOG_DEBUG, "marker 0x%.4X at pos 0x%x\n", marker, s->buf - s->buf_start - 4); + av_log(s->avctx, AV_LOG_DEBUG, "marker 0x%.4X at pos 0x%tx\n", marker, s->buf - s->buf_start - 4); oldbuf = s->buf; if (marker == J2K_SOD){ @@ -1058,16 +1068,15 @@ static av_cold int decode_end(AVCodecContext *avctx) } AVCodec ff_jpeg2000_decoder = { - "j2k", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_JPEG2000, - sizeof(J2kDecoderContext), - j2kdec_init, - NULL, - decode_end, - decode_frame, + .name = "j2k", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_JPEG2000, + .priv_data_size = sizeof(J2kDecoderContext), + .init = j2kdec_init, + .close = decode_end, + .decode = decode_frame, .capabilities = CODEC_CAP_EXPERIMENTAL, .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), .pix_fmts = - (enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, -1} + (enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, PIX_FMT_NONE} };