X-Git-Url: https://git.piment-noir.org/?p=deb_ffmpeg.git;a=blobdiff_plain;f=ffmpeg%2Flibavcodec%2Fdvdsubdec.c;h=222c71bdcf4d15de2b868267f971facc3b516d27;hp=39604f3adae5d3d720e133622af4ccf084a2f92d;hb=HEAD;hpb=092a91210f1b986dc846dc52988518f8f913eb72 diff --git a/ffmpeg/libavcodec/dvdsubdec.c b/ffmpeg/libavcodec/dvdsubdec.c index 39604f3..222c71b 100644 --- a/ffmpeg/libavcodec/dvdsubdec.c +++ b/ffmpeg/libavcodec/dvdsubdec.c @@ -39,7 +39,7 @@ typedef struct DVDSubContext int has_palette; uint8_t colormap[4]; uint8_t alpha[256]; - uint8_t *buf; + uint8_t buf[0x10000]; int buf_size; int forced_subs_only; #ifdef DEBUG @@ -108,6 +108,12 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, int x, y, len, color; uint8_t *d; + if (start >= buf_size) + return -1; + + if (w <= 0 || h <= 0) + return -1; + bit_len = (buf_size - start) * 8; init_get_bits(&gb, buf + start, bit_len); @@ -359,10 +365,12 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect)); sub_header->num_rects = 1; sub_header->rects[0]->pict.data[0] = bitmap; - decode_rle(bitmap, w * 2, w, (h + 1) / 2, - buf, offset1, buf_size, is_8bit); - decode_rle(bitmap + w, w * 2, w, h / 2, - buf, offset2, buf_size, is_8bit); + if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, + buf, offset1, buf_size, is_8bit) < 0) + goto fail; + if (decode_rle(bitmap + w, w * 2, w, h / 2, + buf, offset2, buf_size, is_8bit) < 0) + goto fail; sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); if (is_8bit) { if (!yuv_palette) @@ -501,15 +509,11 @@ static int append_to_cached_buf(AVCodecContext *avctx, { DVDSubContext *ctx = avctx->priv_data; - if (ctx->buf_size > 0xffff - buf_size) { + if (ctx->buf_size >= sizeof(ctx->buf) - buf_size) { av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct " "too large SPU packets aborted.\n"); - av_freep(&ctx->buf); return AVERROR_INVALIDDATA; } - ctx->buf = av_realloc(ctx->buf, ctx->buf_size + buf_size); - if (!ctx->buf) - return AVERROR(ENOMEM); memcpy(ctx->buf + ctx->buf_size, buf, buf_size); ctx->buf_size += buf_size; return 0; @@ -525,7 +529,7 @@ static int dvdsub_decode(AVCodecContext *avctx, AVSubtitle *sub = data; int is_menu; - if (ctx->buf) { + if (ctx->buf_size) { int ret = append_to_cached_buf(avctx, buf, buf_size); if (ret < 0) { *data_size = 0; @@ -567,7 +571,6 @@ static int dvdsub_decode(AVCodecContext *avctx, } #endif - av_freep(&ctx->buf); ctx->buf_size = 0; *data_size = 1; return buf_size; @@ -711,7 +714,6 @@ static av_cold int dvdsub_init(AVCodecContext *avctx) static av_cold int dvdsub_close(AVCodecContext *avctx) { DVDSubContext *ctx = avctx->priv_data; - av_freep(&ctx->buf); ctx->buf_size = 0; return 0; }