diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2013-07-13 11:34:22 +0200 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2013-07-13 11:34:22 +0200 |
commit | c6ae80928eb34e2c5074898bb7b8daf6d13d4399 (patch) | |
tree | 5763dde7b5368694b6f2b06e88c17f41265828a1 /gst-libs/ext/libav/libavcodec | |
parent | 5381cf2c78e986847d3948ac68752d981490f53b (diff) |
Imported Upstream version 1.0.8
Diffstat (limited to 'gst-libs/ext/libav/libavcodec')
20 files changed, 297 insertions, 208 deletions
diff --git a/gst-libs/ext/libav/libavcodec/4xm.c b/gst-libs/ext/libav/libavcodec/4xm.c index 0d4f036..77d15d5 100644 --- a/gst-libs/ext/libav/libavcodec/4xm.c +++ b/gst-libs/ext/libav/libavcodec/4xm.c @@ -343,6 +343,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo decode_p_block(f, dst , src , log2w, log2h, stride); decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride); }else if(code == 3 && f->version<2){ + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ src += f->mv[bytestream2_get_byte(&f->g)]; @@ -352,6 +356,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo } mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2)); }else if(code == 5){ + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2)); }else if(code == 6){ if(log2w){ @@ -633,8 +641,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ color[0]= bytestream2_get_le16u(&g3); color[1]= bytestream2_get_le16u(&g3); - if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); - if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + if(color[0]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); + if(color[1]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n"); color[2]= mix(color[0], color[1]); color[3]= mix(color[1], color[0]); @@ -663,6 +671,9 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ unsigned int prestream_size; const uint8_t *prestream; + if (bitstream_size > (1 << 26)) + return AVERROR_INVALIDDATA; + if (length < bitstream_size + 12) { av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); return AVERROR_INVALIDDATA; @@ -673,13 +684,16 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ prestream = buf + bitstream_size + 12; if(prestream_size + bitstream_size + 12 != length - || bitstream_size > (1<<26) || prestream_size > (1<<26)){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); return -1; } - prestream= read_huffman_tables(f, prestream); + prestream = read_huffman_tables(f, prestream); + if (!prestream) { + av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n"); + return AVERROR_INVALIDDATA; + } init_get_bits(&f->gb, buf + 4, 8*bitstream_size); @@ -765,6 +779,9 @@ static int decode_frame(AVCodecContext *avctx, av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); } + if (f->version <= 1) + return AVERROR_INVALIDDATA; + cfrm->size= cfrm->id= 0; frame_4cc= AV_RL32("pfrm"); }else @@ -807,6 +824,7 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } + memset(f->last_picture.data[0], 0, avctx->height * FFABS(f->last_picture.linesize[0])); } p->pict_type= AV_PICTURE_TYPE_P; diff --git a/gst-libs/ext/libav/libavcodec/aacdec.c b/gst-libs/ext/libav/libavcodec/aacdec.c index 6478c77..24e6ca6 100644 --- a/gst-libs/ext/libav/libavcodec/aacdec.c +++ b/gst-libs/ext/libav/libavcodec/aacdec.c @@ -192,6 +192,8 @@ static av_cold int che_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_ELEM_ID], int type, int id, int *channels) { + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; if (che_pos[type][id]) { if (!ac->che[type][id]) { if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) diff --git a/gst-libs/ext/libav/libavcodec/bmv.c b/gst-libs/ext/libav/libavcodec/bmv.c index 49346a4..920e752 100644 --- a/gst-libs/ext/libav/libavcodec/bmv.c +++ b/gst-libs/ext/libav/libavcodec/bmv.c @@ -134,7 +134,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, mode += 1 + advance_mode; if (mode >= 4) mode -= 3; - if (FFABS(dst_end - dst) < len) + if (len <= 0 || FFABS(dst_end - dst) < len) return -1; switch (mode) { case 1: diff --git a/gst-libs/ext/libav/libavcodec/dfa.c b/gst-libs/ext/libav/libavcodec/dfa.c index c2f8002..0ae89a8 100644 --- a/gst-libs/ext/libav/libavcodec/dfa.c +++ b/gst-libs/ext/libav/libavcodec/dfa.c @@ -258,6 +258,8 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height segments = bytestream2_get_le16(gb); } line_ptr = frame; + if (frame_end - frame < width) + return AVERROR_INVALIDDATA; frame += width; y++; while (segments--) { diff --git a/gst-libs/ext/libav/libavcodec/dv.c b/gst-libs/ext/libav/libavcodec/dv.c index 03a05b3..6f74e7b 100644 --- a/gst-libs/ext/libav/libavcodec/dv.c +++ b/gst-libs/ext/libav/libavcodec/dv.c @@ -372,11 +372,6 @@ typedef struct BlockInfo { static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - /* decode AC coefficients */ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) { diff --git a/gst-libs/ext/libav/libavcodec/get_bits.h b/gst-libs/ext/libav/libavcodec/get_bits.h index 64393bc..dc348c7 100644 --- a/gst-libs/ext/libav/libavcodec/get_bits.h +++ b/gst-libs/ext/libav/libavcodec/get_bits.h @@ -344,20 +344,27 @@ static inline int check_marker(GetBitContext *s, const char *msg) } /** - * Inititalize GetBitContext. - * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger than the actual read bits - * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. */ -static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) +static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, + int bit_size) { - int buffer_size = (bit_size+7)>>3; - if (buffer_size < 0 || bit_size < 0) { + int buffer_size; + int ret = 0; + + if (bit_size > INT_MAX - 7 || bit_size <= 0) { buffer_size = bit_size = 0; buffer = NULL; + ret = AVERROR_INVALIDDATA; } + buffer_size = (bit_size + 7) >> 3; + s->buffer = buffer; s->size_in_bits = bit_size; #if !UNCHECKED_BITSTREAM_READER @@ -365,6 +372,7 @@ static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer, #endif s->buffer_end = buffer + buffer_size; s->index = 0; + return ret; } static inline void align_get_bits(GetBitContext *s) diff --git a/gst-libs/ext/libav/libavcodec/indeo3.c b/gst-libs/ext/libav/libavcodec/indeo3.c index 2aa8d95..9e90fb1 100644 --- a/gst-libs/ext/libav/libavcodec/indeo3.c +++ b/gst-libs/ext/libav/libavcodec/indeo3.c @@ -222,7 +222,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) * @param plane pointer to the plane descriptor * @param cell pointer to the cell descriptor */ -static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) +static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) { int h, w, mv_x, mv_y, offset, offset_dst; uint8_t *src, *dst; @@ -232,6 +232,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) dst = plane->pixels[ctx->buf_sel] + offset_dst; mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y > plane->height || + ((cell->xpos + cell->width) << 2) + mv_x > plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset = offset_dst + mv_y * plane->pitch + mv_x; src = plane->pixels[ctx->buf_sel ^ 1] + offset; @@ -259,6 +269,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) dst += 4; } } + + return 0; } @@ -584,11 +596,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } else if (mode >= 10) { /* for mode 10 and 11 INTER first copy the predicted cell into the current one */ /* so we don't need to do data copying for each RLE code later */ - copy_cell(ctx, plane, cell); + int ret = copy_cell(ctx, plane, cell); + if (ret < 0) + return ret; } else { /* set the pointer to the reference pixels for modes 0-4 INTER */ mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y > plane->height || + ((cell->xpos + cell->width) << 2) + mv_x > plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset += mv_y * plane->pitch + mv_x; ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset; } @@ -720,7 +744,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const int depth, const int strip_width) { Cell curr_cell; - int bytes_used; + int bytes_used, ret; if (depth <= 0) { av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); @@ -771,8 +795,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, CHECK_CELL if (!curr_cell.mv_ptr) return AVERROR_INVALIDDATA; - copy_cell(ctx, plane, &curr_cell); - return 0; + ret = copy_cell(ctx, plane, &curr_cell); + return ret; } break; case INTER_DATA: @@ -855,17 +879,20 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const uint8_t *buf, int buf_size) { - const uint8_t *buf_ptr = buf, *bs_hdr; + GetByteContext gb; + const uint8_t *bs_hdr; uint32_t frame_num, word2, check_sum, data_size; uint32_t y_offset, u_offset, v_offset, starts[3], ends[3]; uint16_t height, width; int i, j; + bytestream2_init(&gb, buf, buf_size); + /* parse and check the OS header */ - frame_num = bytestream_get_le32(&buf_ptr); - word2 = bytestream_get_le32(&buf_ptr); - check_sum = bytestream_get_le32(&buf_ptr); - data_size = bytestream_get_le32(&buf_ptr); + frame_num = bytestream2_get_le32(&gb); + word2 = bytestream2_get_le32(&gb); + check_sum = bytestream2_get_le32(&gb); + data_size = bytestream2_get_le32(&gb); if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) { av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n"); @@ -873,28 +900,27 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } /* parse the bitstream header */ - bs_hdr = buf_ptr; + bs_hdr = gb.buffer; - if (bytestream_get_le16(&buf_ptr) != 32) { + if (bytestream2_get_le16(&gb) != 32) { av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n"); return AVERROR_INVALIDDATA; } ctx->frame_num = frame_num; - ctx->frame_flags = bytestream_get_le16(&buf_ptr); - ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3; - ctx->cb_offset = *buf_ptr++; + ctx->frame_flags = bytestream2_get_le16(&gb); + ctx->data_size = (bytestream2_get_le32(&gb) + 7) >> 3; + ctx->cb_offset = bytestream2_get_byte(&gb); if (ctx->data_size == 16) return 4; - if (ctx->data_size > buf_size) - ctx->data_size = buf_size; + ctx->data_size = FFMIN(ctx->data_size, buf_size - 16); - buf_ptr += 3; // skip reserved byte and checksum + bytestream2_skip(&gb, 3); // skip reserved byte and checksum /* check frame dimensions */ - height = bytestream_get_le16(&buf_ptr); - width = bytestream_get_le16(&buf_ptr); + height = bytestream2_get_le16(&gb); + width = bytestream2_get_le16(&gb); if (av_image_check_size(width, height, 0, avctx)) return AVERROR_INVALIDDATA; @@ -920,9 +946,10 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, avcodec_set_dimensions(avctx, width, height); } - y_offset = bytestream_get_le32(&buf_ptr); - v_offset = bytestream_get_le32(&buf_ptr); - u_offset = bytestream_get_le32(&buf_ptr); + y_offset = bytestream2_get_le32(&gb); + v_offset = bytestream2_get_le32(&gb); + u_offset = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); /* unfortunately there is no common order of planes in the buffer */ /* so we use that sorting algo for determining planes data sizes */ @@ -941,6 +968,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->v_data_size = ends[1] - starts[1]; ctx->u_data_size = ends[2] - starts[2]; if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || + FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 || FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) { av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n"); return AVERROR_INVALIDDATA; @@ -949,7 +977,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->y_data_ptr = bs_hdr + y_offset; ctx->v_data_ptr = bs_hdr + v_offset; ctx->u_data_ptr = bs_hdr + u_offset; - ctx->alt_quant = buf_ptr + sizeof(uint32_t); + ctx->alt_quant = gb.buffer; if (ctx->data_size == 16) { av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n"); diff --git a/gst-libs/ext/libav/libavcodec/ivi_common.c b/gst-libs/ext/libav/libavcodec/ivi_common.c index 00205ae..c907e2a 100644 --- a/gst-libs/ext/libav/libavcodec/ivi_common.c +++ b/gst-libs/ext/libav/libavcodec/ivi_common.c @@ -39,6 +39,9 @@ extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tabl VLC ff_ivi_mb_vlc_tabs [8]; VLC ff_ivi_blk_vlc_tabs[8]; +typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, + uint32_t pitch, int mc_type); + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -74,7 +77,7 @@ int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) bits[pos] = i + cb->xbits[i] + not_last_row; if (bits[pos] > IVI_VLC_BITS) - return -1; /* invalid descriptor */ + return AVERROR_INVALIDDATA; /* invalid descriptor */ codewords[pos] = inv_bits((prefix | j), bits[pos]); if (!bits[pos]) @@ -343,8 +346,7 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) uint32_t cbp, sym, lo, hi, quant, buf_offs, q; IVIMbInfo *mb; RVMapDesc *rvmap = band->rv_map; - void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); + ivi_mc_func mc_with_delta_func, mc_no_delta_func; const uint16_t *base_tab; const uint8_t *scale_tab; @@ -433,7 +435,7 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) } else { if (sym >= 256U) { av_log(NULL, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); - return -1; + return AVERROR_INVALIDDATA; } run = rvmap->runtab[sym]; val = rvmap->valtab[sym]; @@ -456,7 +458,7 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) }// while if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) - return -1; /* corrupt block data */ + return AVERROR_INVALIDDATA; /* corrupt block data */ /* undoing DC coeff prediction for intra-blocks */ if (is_intra && band->is_2d_trans) { @@ -514,8 +516,7 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVIMbInfo *mb, *ref_mb; const int16_t *src; int16_t *dst; - void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, - int mc_type); + ivi_mc_func mc_no_delta_func; if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches " @@ -550,7 +551,7 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, if (band->inherit_qdelta && ref_mb) mb->q_delta = ref_mb->q_delta; - if (band->inherit_mv) { + if (band->inherit_mv && ref_mb) { /* motion vector inheritance */ if (mv_scale) { mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); @@ -737,8 +738,16 @@ static int decode_band(IVI45DecContext *ctx, int plane_num, break; result = ff_ivi_decode_blocks(&ctx->gb, band, tile); - if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); + if (result < 0) { + av_log(avctx, AV_LOG_ERROR, + "Corrupted tile data encountered!\n"); + break; + } + + if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { + av_log(avctx, AV_LOG_ERROR, + "Tile data_size mismatch!\n"); + result = AVERROR_INVALIDDATA; break; } @@ -786,14 +795,14 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); - return -1; + return result; } if (ctx->gop_invalid) return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); - return -1; + return AVERROR_PATCHWELCOME; } ctx->switch_buffers(ctx); @@ -804,10 +813,10 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, for (p = 0; p < 3; p++) { for (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p); - return -1; + return result; } } } diff --git a/gst-libs/ext/libav/libavcodec/jpeglsdec.c b/gst-libs/ext/libav/libavcodec/jpeglsdec.c index a4cfe4f..d234d73 100644 --- a/gst-libs/ext/libav/libavcodec/jpeglsdec.c +++ b/gst-libs/ext/libav/libavcodec/jpeglsdec.c @@ -71,13 +71,13 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) case 2: case 3: av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); - return -1; + return AVERROR(ENOSYS); case 4: av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); - return -1; + return AVERROR(ENOSYS); default: av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); - return -1; + return AVERROR_INVALIDDATA; } // av_log(s->avctx, AV_LOG_DEBUG, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); @@ -260,7 +260,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor int i, t = 0; uint8_t *zero, *last, *cur; JLSState *state; - int off = 0, stride = 1, width, shift; + int off = 0, stride = 1, width, shift, ret = 0; zero = av_mallocz(s->picture_ptr->linesize[0]); last = zero; @@ -286,6 +286,10 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor // av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",s->width,s->height,state->near,state->maxval,state->T1,state->T2,state->T3,state->reset,state->limit,state->qbpp, state->range); // av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", ilv, point_transform, s->bits, s->cur_scan); if(ilv == 0) { /* separate planes */ + if (s->cur_scan > s->nb_components) { + ret = AVERROR_INVALIDDATA; + goto end; + } off = s->cur_scan - 1; stride = (s->nb_components > 1) ? 3 : 1; width = s->width * stride; @@ -324,11 +328,10 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor last = cur; cur += s->picture_ptr->linesize[0]; } - } else if(ilv == 2) { /* sample interleaving */ + } else if (ilv == 2) { /* sample interleaving */ av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); - av_free(state); - av_free(zero); - return -1; + ret = AVERROR_PATCHWELCOME; + goto end; } if(shift){ /* we need to do point transform or normalize samples */ @@ -356,10 +359,12 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor } } } + +end: av_free(state); av_free(zero); - return 0; + return ret; } diff --git a/gst-libs/ext/libav/libavcodec/kmvc.c b/gst-libs/ext/libav/libavcodec/kmvc.c index a6bb13b..4ed7811 100644 --- a/gst-libs/ext/libav/libavcodec/kmvc.c +++ b/gst-libs/ext/libav/libavcodec/kmvc.c @@ -29,6 +29,8 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" +#include "libavutil/common.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 @@ -46,7 +48,7 @@ typedef struct KmvcContext { int palsize; uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; - uint8_t *frm0, *frm1; + uint8_t frm0[320 * 200], frm1[320 * 200]; GetByteContext g; } KmvcContext; @@ -55,7 +57,7 @@ typedef struct BitBuf { int bitbuf; } BitBuf; -#define BLK(data, x, y) data[(x) + (y) * 320] +#define BLK(data, x, y) data[av_clip((x) + (y) * 320, 0, 320 * 200 -1)] #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g); @@ -367,8 +369,6 @@ static av_cold int decode_init(AVCodecContext * avctx) return -1; } - c->frm0 = av_mallocz(320 * 200); - c->frm1 = av_mallocz(320 * 200); c->cur = c->frm0; c->prev = c->frm1; @@ -401,30 +401,12 @@ static av_cold int decode_init(AVCodecContext * avctx) return 0; } - - -/* - * Uninit kmvc decoder - */ -static av_cold int decode_end(AVCodecContext * avctx) -{ - KmvcContext *const c = avctx->priv_data; - - av_freep(&c->frm0); - av_freep(&c->frm1); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - AVCodec ff_kmvc_decoder = { .name = "kmvc", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_KMVC, .priv_data_size = sizeof(KmvcContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), diff --git a/gst-libs/ext/libav/libavcodec/mjpegdec.c b/gst-libs/ext/libav/libavcodec/mjpegdec.c index 542de98..5256a8e 100644 --- a/gst-libs/ext/libav/libavcodec/mjpegdec.c +++ b/gst-libs/ext/libav/libavcodec/mjpegdec.c @@ -266,6 +266,13 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) return -1; + if (!s->h_count[i] || !s->v_count[i]) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid sampling factor in component %d %d:%d\n", + i, s->h_count[i], s->v_count[i]); + return AVERROR_INVALIDDATA; + } + av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], s->v_count[i], s->component_id[i], s->quant_index[i]); @@ -711,10 +718,9 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, } static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, - int point_transform) + int point_transform, int nb_components) { int i, mb_x, mb_y; - const int nb_components = 3; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { @@ -957,6 +963,11 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]]; GetBitContext mb_bitmask_gb; + if (ss < 0 || ss >= 64 || + se < ss || se >= 64 || + Ah < 0 || Al < 0) + return AVERROR_INVALIDDATA; + if (mb_bitmask) init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); @@ -1108,7 +1119,8 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, if (ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0) return -1; } else { - if (ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0) + if (ljpeg_decode_yuv_scan(s, predictor, point_transform, + nb_components)) return -1; } } @@ -1489,6 +1501,12 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, else if (start_code == COM) mjpeg_decode_com(s); + if (!CONFIG_JPEGLS_DECODER && + (start_code == SOF48 || start_code == LSE)) { + av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n"); + return AVERROR(ENOSYS); + } + switch (start_code) { case SOI: s->restart_interval = 0; diff --git a/gst-libs/ext/libav/libavcodec/proresdec.c b/gst-libs/ext/libav/libavcodec/proresdec.c index 031760c..bc99665 100644 --- a/gst-libs/ext/libav/libavcodec/proresdec.c +++ b/gst-libs/ext/libav/libavcodec/proresdec.c @@ -186,6 +186,8 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, if (ctx->frame_type) { /* if interlaced */ ctx->picture.interlaced_frame = 1; ctx->picture.top_field_first = ctx->frame_type & 1; + } else { + ctx->picture.interlaced_frame = 0; } ctx->alpha_info = buf[17] & 0xf; diff --git a/gst-libs/ext/libav/libavcodec/put_bits.h b/gst-libs/ext/libav/libavcodec/put_bits.h index 6e81267..905461a 100644 --- a/gst-libs/ext/libav/libavcodec/put_bits.h +++ b/gst-libs/ext/libav/libavcodec/put_bits.h @@ -73,6 +73,14 @@ static inline int put_bits_count(PutBitContext *s) } /** + * @return the number of bits available in the bitstream. + */ +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; +} + +/** * Pad the end of the output stream with zeros. */ static inline void flush_put_bits(PutBitContext *s) diff --git a/gst-libs/ext/libav/libavcodec/qdm2.c b/gst-libs/ext/libav/libavcodec/qdm2.c index 739971e..59bce40 100644 --- a/gst-libs/ext/libav/libavcodec/qdm2.c +++ b/gst-libs/ext/libav/libavcodec/qdm2.c @@ -1881,6 +1881,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); return -1; } + if (s->fft_size != (1 << (s->fft_order - 1))) { + av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size); + return AVERROR_INVALIDDATA; + } ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R); ff_mpadsp_init(&s->mpadsp); diff --git a/gst-libs/ext/libav/libavcodec/rv10.c b/gst-libs/ext/libav/libavcodec/rv10.c index 58604d1..4f64ec2 100644 --- a/gst-libs/ext/libav/libavcodec/rv10.c +++ b/gst-libs/ext/libav/libavcodec/rv10.c @@ -341,6 +341,11 @@ static int rv20_decode_picture_header(MpegEncContext *s) f = get_bits(&s->gb, rpr_bits); if(f){ + if (s->avctx->extradata_size < 8 + 2 * f) { + av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n"); + return AVERROR_INVALIDDATA; + } + new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f]; new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f]; }else{ diff --git a/gst-libs/ext/libav/libavcodec/smacker.c b/gst-libs/ext/libav/libavcodec/smacker.c index 3928d8f..e9192ff 100644 --- a/gst-libs/ext/libav/libavcodec/smacker.c +++ b/gst-libs/ext/libav/libavcodec/smacker.c @@ -252,7 +252,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int ctx.recode2 = tmp2.values; ctx.last = last; - huff.length = ((size + 3) >> 2) + 3; + huff.length = ((size + 3) >> 2) + 4; huff.maxlength = 0; huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); @@ -648,7 +648,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); - smacker_decode_tree(&gb, &h[i], 0, 0); + if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { + for (; i >= 0; i--) { + if (vlc[i].table) + ff_free_vlc(&vlc[i]); + av_free(h[i].bits); + av_free(h[i].lengths); + av_free(h[i].values); + } + return AVERROR_INVALIDDATA; + } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, diff --git a/gst-libs/ext/libav/libavcodec/tiff.c b/gst-libs/ext/libav/libavcodec/tiff.c index a0db1f1..8a1db12 100644 --- a/gst-libs/ext/libav/libavcodec/tiff.c +++ b/gst-libs/ext/libav/libavcodec/tiff.c @@ -186,10 +186,13 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin break; case TIFF_PACKBITS: for(pixels = 0; pixels < width;){ + if (ssrc + size - src < 2) + return AVERROR_INVALIDDATA; code = (int8_t)*src++; if(code >= 0){ code++; - if(pixels + code > width){ + if (pixels + code > width || + ssrc + size - src < code) { av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); return -1; } diff --git a/gst-libs/ext/libav/libavcodec/vmdav.c b/gst-libs/ext/libav/libavcodec/vmdav.c index 570c362..4659971 100644 --- a/gst-libs/ext/libav/libavcodec/vmdav.c +++ b/gst-libs/ext/libav/libavcodec/vmdav.c @@ -45,6 +45,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bytestream.h" #define VMD_HEADER_SIZE 0x330 #define PALETTE_COUNT 256 @@ -75,8 +76,6 @@ typedef struct VmdVideoContext { static void lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len) { - const unsigned char *s; - unsigned int s_len; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -87,18 +86,17 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned int speclen; unsigned char tag; unsigned int i, j; + GetByteContext gb; - s = src; - s_len = src_len; + bytestream2_init(&gb, src, src_len); d = dest; d_end = d + dest_len; - dataleft = AV_RL32(s); - s += 4; s_len -= 4; + dataleft = bytestream2_get_le32(&gb); memset(queue, 0x20, QUEUE_SIZE); - if (s_len < 4) + if (bytestream2_get_bytes_left(&gb) < 4) return; - if (AV_RL32(s) == 0x56781234) { - s += 4; s_len -= 4; + if (bytestream2_peek_le32(&gb) == 0x56781234) { + bytestream2_get_le32(&gb); qpos = 0x111; speclen = 0xF + 3; } else { @@ -106,40 +104,32 @@ static void lz_unpack(const unsigned char *src, int src_len, speclen = 100; /* no speclen */ } - while (dataleft > 0 && s_len > 0) { - tag = *s++; s_len--; + while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) { + tag = bytestream2_get_byteu(&gb); if ((tag == 0xFF) && (dataleft > 8)) { - if (d + 8 > d_end || s_len < 8) + if (d + 8 > d_end || bytestream2_get_bytes_left(&gb) < 8) return; for (i = 0; i < 8; i++) { - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); qpos &= QUEUE_MASK; } - s_len -= 8; dataleft -= 8; } else { for (i = 0; i < 8; i++) { if (dataleft == 0) break; if (tag & 0x01) { - if (d + 1 > d_end || s_len < 1) + if (d + 1 > d_end || bytestream2_get_bytes_left(&gb) < 1) return; - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byte(&gb); qpos &= QUEUE_MASK; dataleft--; - s_len--; } else { - if (s_len < 2) - return; - chainofs = *s++; - chainofs |= ((*s & 0xF0) << 4); - chainlen = (*s++ & 0x0F) + 3; - s_len -= 2; + chainofs = bytestream2_get_byte(&gb); + chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4); + chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3; if (chainlen == speclen) { - if (s_len < 1) - return; - chainlen = *s++ + 0xF + 3; - s_len--; + chainlen = bytestream2_get_byte(&gb) + 0xF + 3; } if (d + chainlen > d_end) return; @@ -159,49 +149,44 @@ static void lz_unpack(const unsigned char *src, int src_len, static int rle_unpack(const unsigned char *src, unsigned char *dest, int src_count, int src_size, int dest_len) { - const unsigned char *ps; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; + GetByteContext gb; - ps = src; + bytestream2_init(&gb, src, src_size); pd = dest; if (src_count & 1) { - if (src_size < 1) + if (bytestream2_get_bytes_left(&gb) < 1) return 0; - *pd++ = *ps++; - src_size--; + *pd++ = bytestream2_get_byteu(&gb); } src_count >>= 1; i = 0; do { - if (src_size < 1) + if (bytestream2_get_bytes_left(&gb) < 1) break; - l = *ps++; - src_size--; + l = bytestream2_get_byteu(&gb); if (l & 0x80) { l = (l & 0x7F) * 2; - if (pd + l > dest_end || src_size < l) - return ps - src; - memcpy(pd, ps, l); - ps += l; - src_size -= l; + if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < l) + return bytestream2_tell(&gb); + bytestream2_get_buffer(&gb, pd, l); pd += l; } else { - if (pd + i > dest_end || src_size < 2) - return ps - src; + if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2) + return bytestream2_tell(&gb); for (i = 0; i < l; i++) { - *pd++ = ps[0]; - *pd++ = ps[1]; + *pd++ = bytestream2_get_byteu(&gb); + *pd++ = bytestream2_get_byteu(&gb); } - ps += 2; - src_size -= 2; + bytestream2_skip(&gb, 2); } i += l; } while (i < src_count); - return ps - src; + return bytestream2_tell(&gb); } static void vmd_decode(VmdVideoContext *s) @@ -210,11 +195,8 @@ static void vmd_decode(VmdVideoContext *s) unsigned int *palette32; unsigned char r, g, b; - /* point to the start of the encoded data */ - const unsigned char *p = s->buf + 16; + GetByteContext gb; - const unsigned char *pb; - unsigned int pb_size; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -259,30 +241,31 @@ static void vmd_decode(VmdVideoContext *s) } /* check if there is a new palette */ + bytestream2_init(&gb, s->buf + 16, s->size - 16); if (s->buf[15] & 0x02) { - p += 2; + bytestream2_skip(&gb, 2); palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *p++ * 4; - g = *p++ * 4; - b = *p++ * 4; - palette32[i] = (r << 16) | (g << 8) | (b); + if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) { + for (i = 0; i < PALETTE_COUNT; i++) { + r = bytestream2_get_byteu(&gb) * 4; + g = bytestream2_get_byteu(&gb) * 4; + b = bytestream2_get_byteu(&gb) * 4; + palette32[i] = (r << 16) | (g << 8) | (b); + } } s->size -= (256 * 3 + 2); } if (s->size > 0) { /* originally UnpackFrame in VAG's code */ - pb = p; - pb_size = s->buf + s->size - pb; - if (pb_size < 1) + bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer); + if (bytestream2_get_bytes_left(&gb) < 1) return; - meth = *pb++; pb_size--; + meth = bytestream2_get_byteu(&gb); if (meth & 0x80) { - lz_unpack(pb, pb_size, + lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; - pb = s->unpack_buffer; - pb_size = s->unpack_buffer_size; + bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; @@ -292,17 +275,12 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_size < 1) - return; - len = *pb++; - pb_size--; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_size < len) + if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len) return; - memcpy(&dp[ofs], pb, len); - pb += len; - pb_size -= len; + bytestream2_get_buffer(&gb, &dp[ofs], len); ofs += len; } else { /* interframe pixel copy */ @@ -324,11 +302,7 @@ static void vmd_decode(VmdVideoContext *s) case 2: for (i = 0; i < frame_height; i++) { - if (pb_size < frame_width) - return; - memcpy(dp, pb, frame_width); - pb += frame_width; - pb_size -= frame_width; + bytestream2_get_buffer(&gb, dp, frame_width); dp += s->frame.linesize[0]; pp += s->prev_frame.linesize[0]; } @@ -338,24 +312,16 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_size < 1) - return; - len = *pb++; - pb_size--; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (pb_size < 1) - return; - if (*pb++ == 0xFF) - len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs); - else { - if (pb_size < len) - return; - memcpy(&dp[ofs], pb, len); - } - pb += len; - pb_size -= 1 + len; - ofs += len; + if (bytestream2_get_byte(&gb) == 0xFF) + len = rle_unpack(gb.buffer, &dp[ofs], + len, bytestream2_get_bytes_left(&gb), + frame_width - ofs); + else + bytestream2_get_buffer(&gb, &dp[ofs], len); + bytestream2_skip(&gb, len); } else { /* interframe pixel copy */ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) diff --git a/gst-libs/ext/libav/libavcodec/wavpack.c b/gst-libs/ext/libav/libavcodec/wavpack.c index 1098873..31377e7 100644 --- a/gst-libs/ext/libav/libavcodec/wavpack.c +++ b/gst-libs/ext/libav/libavcodec/wavpack.c @@ -773,13 +773,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) { av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n"); - return -1; + return AVERROR_INVALIDDATA; } s = wc->fdec[block_no]; if (!s) { av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no); - return -1; + return AVERROR_INVALIDDATA; } memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); @@ -790,6 +790,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (!wc->mkv_mode) { s->samples = AV_RL32(buf); buf += 4; + if (s->samples != wc->samples) + return AVERROR_INVALIDDATA; + if (!s->samples) { *got_frame_ptr = 0; return 0; @@ -1018,7 +1021,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_CHANINFO: if (size <= 1) { av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n"); - return -1; + return AVERROR_INVALIDDATA; } chan = *buf++; switch (size - 2) { @@ -1037,10 +1040,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, chmask = avctx->channel_layout; } if (chan != avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Block reports total %d channels, " - "decoder believes it's %d channels\n", chan, - avctx->channels); - return -1; + av_log(avctx, AV_LOG_ERROR, + "Block reports total %d channels, " + "decoder believes it's %d channels\n", + chan, avctx->channels); + return AVERROR_INVALIDDATA; } if (!avctx->channel_layout) avctx->channel_layout = chmask; @@ -1055,31 +1059,31 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (!got_terms) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_weights) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_samples) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_entropy) { av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->hybrid && !got_hybrid) { av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_bs) { av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) { const int size = get_bits_left(&s->gb_extra_bits); @@ -1099,7 +1103,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; samplecount >>= 1; } else { @@ -1113,7 +1117,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) { int16_t *dst = (int16_t*)samples + 1; @@ -1168,6 +1172,9 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, int frame_size, ret, frame_flags; int samplecount = 0; + if (avpkt->size < 12 + s->multichannel * 4) + return AVERROR_INVALIDDATA; + s->block = 0; s->ch_offset = 0; @@ -1187,7 +1194,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, if (s->samples <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } if (frame_flags & 0x80) { @@ -1221,13 +1228,13 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d " "vs. %d bytes left)\n", s->block, frame_size, buf_size); wavpack_decode_flush(avctx); - return -1; + return AVERROR_INVALIDDATA; } if ((samplecount = wavpack_decode_block(avctx, s->block, s->frame.data[0], got_frame_ptr, buf, frame_size)) < 0) { wavpack_decode_flush(avctx); - return -1; + return samplecount; } s->block++; buf += frame_size; buf_size -= frame_size; diff --git a/gst-libs/ext/libav/libavcodec/wmaprodec.c b/gst-libs/ext/libav/libavcodec/wmaprodec.c index 1b7797c..902c4e3 100644 --- a/gst-libs/ext/libav/libavcodec/wmaprodec.c +++ b/gst-libs/ext/libav/libavcodec/wmaprodec.c @@ -106,6 +106,7 @@ #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size +#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) ///< minimum block size #define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size #define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes @@ -335,6 +336,12 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Invalid minimum block size %i\n", + s->max_num_subframes); + return AVERROR_INVALIDDATA; + } + if (s->avctx->sample_rate <= 0) { av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); return AVERROR_INVALIDDATA; @@ -428,7 +435,8 @@ static av_cold int decode_init(AVCodecContext *avctx) for (x = 0; x < num_possible_block_sizes; x++) { int v = 0; while (s->sfb_offsets[x][v + 1] << x < offset) - ++v; + if (++v >= MAX_BANDS) + return AVERROR_INVALIDDATA; s->sf_offsets[i][x][b] = v; } } @@ -720,6 +728,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) if (get_bits1(&s->gb)) { av_log_ask_for_sample(s->avctx, "unsupported channel transform type\n"); + return AVERROR_PATCHWELCOME; } } else { chgroup->transform = 1; @@ -1122,11 +1131,12 @@ static int decode_subframe(WMAProDecodeCtx *s) cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; /** configure the decoder for the current subframe */ + offset += s->samples_per_frame >> 1; + for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) - + offset]; + s->channel[c].coeffs = &s->channel[c].out[offset]; } s->subframe_len = subframe_len; @@ -1177,7 +1187,7 @@ static int decode_subframe(WMAProDecodeCtx *s) for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; - if (num_vec_coeffs > WMAPRO_BLOCK_MAX_SIZE) { + if (num_vec_coeffs + offset > FF_ARRAY_ELEMS(s->channel[c].out)) { av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); return AVERROR_INVALIDDATA; } @@ -1466,6 +1476,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, return; } + if (len > put_bits_left(&s->pb)) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot append %d bits, only %d bits available.\n", + len, put_bits_left(&s->pb)); + s->packet_loss = 1; + return; + } + s->num_saved_bits += len; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), |