aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-07-29 02:29:23 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-07-29 02:35:24 +0200
commitbe90f0279d0784c396407e152a8d817953381886 (patch)
treef42c67762d6851b9002e31901632decb0e3b9ebd /libavcodec
parentf3c300d0a4d326c19013d6ecc8ce7d1d25729aa5 (diff)
parent43c0a87279e717c1384314c6da7155c306ee7c60 (diff)
downloadffmpeg-be90f0279d0784c396407e152a8d817953381886.tar.gz
Merge commit '43c0a87279e717c1384314c6da7155c306ee7c60' into release/0.10
* commit '43c0a87279e717c1384314c6da7155c306ee7c60': qdm2: check that the FFT size is a power of 2 indeo3: switch parsing the header to bytestream2 indeo3: check motion vectors. rv10: check that extradata is large enough indeo3: fix data size check lavf: make sure stream probe data gets freed. dfa: check for invalid access in decode_wdlt(). xmv: check audio track parameters validity. bmv: check for len being valid in bmv_decode_frame(). xmv: do not leak memory in the error paths in xmv_read_header() avfiltergraph: check for sws opts being non-NULL before using them. oma: Validate sample rates Prepare for 0.8.7 Release Conflicts: RELEASE libavcodec/indeo3.c libavfilter/avfiltergraph.c libavformat/utils.c libavformat/xmv.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/bmv.c2
-rw-r--r--libavcodec/dfa.c2
-rw-r--r--libavcodec/indeo3.c76
-rw-r--r--libavcodec/qdm2.c4
-rw-r--r--libavcodec/rv10.c5
5 files changed, 64 insertions, 25 deletions
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index d2f4e9f86c..951c25c71d 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -138,7 +138,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/libavcodec/dfa.c b/libavcodec/dfa.c
index 827e1f28dc..cde4dc229b 100644
--- a/libavcodec/dfa.c
+++ b/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/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 97c7afdead..c19fffd941 100644
--- a/libavcodec/indeo3.c
+++ b/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;
@@ -235,6 +235,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
mv_x = cell->mv_ptr[1];
}else
mv_x= mv_y= 0;
+
+ /* -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;
@@ -262,6 +272,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
dst += 4;
}
}
+
+ return 0;
}
@@ -587,11 +599,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;
}
@@ -723,7 +747,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");
@@ -774,8 +798,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:
@@ -858,17 +882,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");
@@ -876,28 +903,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;
@@ -923,9 +949,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 */
@@ -944,6 +971,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;
@@ -952,7 +980,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/libavcodec/qdm2.c b/libavcodec/qdm2.c
index aa9c3870c8..be8754103e 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1882,6 +1882,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/libavcodec/rv10.c b/libavcodec/rv10.c
index 9bc35bf697..62266dc2d7 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -358,6 +358,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{