aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-10-25 16:29:54 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-10-25 16:29:54 +0200
commit36487066ee044d580ce2fdf7aa3989a0036e9313 (patch)
tree5ce45d234b430c833a49b36cf522745e002eee85
parentfe8243d7a9e3dae000389ca2020f26679c779f04 (diff)
parent15c2e8027f4827018608badb1bff1294af1810e4 (diff)
downloadffmpeg-36487066ee044d580ce2fdf7aa3989a0036e9313.tar.gz
Merge commit '15c2e8027f4827018608badb1bff1294af1810e4' into release/0.10
* commit '15c2e8027f4827018608badb1bff1294af1810e4': wav: do not fail on empty INFO tags cavsdec: check for changing w/h. indeo4: update AVCodecContext width/height on size change avidec: use actually read size instead of requested size wmaprodec: check num_vec_coeffs for validity lagarith: check count before writing zeros. indeo3: fix out of cell write. indeo5: check tile size in decode_mb_info(). indeo5: prevent null pointer dereference on broken files indeo5dec: Make sure we have had a valid gop header. indeo4/5: check empty tile size in decode_mb_info(). ivi_common: make ff_ivi_process_empty_tile() static. Conflicts: libavcodec/indeo5.c libavformat/wav.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/cavsdec.c13
-rw-r--r--libavcodec/indeo3.c3
-rw-r--r--libavcodec/indeo5.c14
-rw-r--r--libavcodec/ivi_common.c29
-rw-r--r--libavcodec/ivi_common.h14
-rw-r--r--libavcodec/lagarith.c5
-rw-r--r--libavcodec/wmaprodec.c7
-rw-r--r--libavformat/avidec.c2
-rw-r--r--libavformat/wav.c2
9 files changed, 67 insertions, 22 deletions
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index dc13e936fd..0b617061eb 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -609,12 +609,21 @@ static int decode_pic(AVSContext *h) {
static int decode_seq_header(AVSContext *h) {
MpegEncContext *s = &h->s;
int frame_rate_code;
+ int width, height;
h->profile = get_bits(&s->gb,8);
h->level = get_bits(&s->gb,8);
skip_bits1(&s->gb); //progressive sequence
- s->width = get_bits(&s->gb,14);
- s->height = get_bits(&s->gb,14);
+
+ width = get_bits(&s->gb, 14);
+ height = get_bits(&s->gb, 14);
+ if ((s->width || s->height) && (s->width != width || s->height != height)) {
+ av_log_missing_feature(s, "Width/height changing in CAVS is", 0);
+ return AVERROR_PATCHWELCOME;
+ }
+ s->width = width;
+ s->height = height;
+
skip_bits(&s->gb,2); //chroma format
skip_bits(&s->gb,3); //sample_precision
h->aspect_ratio = get_bits(&s->gb,4);
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 6e9a31e080..5479c55a32 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -419,6 +419,9 @@ static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block,
blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2);
line_offset = v_zoom ? row_offset : 0;
+ if (cell->height & v_zoom || cell->width & h_zoom)
+ return IV3_BAD_DATA;
+
for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) {
for (x = 0; x < cell->width; x += 1 + h_zoom) {
ref = ref_block;
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index c5a04c8a43..1d5824faf7 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -309,8 +309,12 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
ctx->frame_num = get_bits(&ctx->gb, 8);
if (ctx->frame_type == FRAMETYPE_INTRA) {
- if (decode_gop_header(ctx, avctx))
- return -1;
+ ctx->gop_invalid = 1;
+ if (decode_gop_header(ctx, avctx)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ctx->gop_invalid = 0;
}
if (ctx->frame_type != FRAMETYPE_NULL) {
@@ -431,6 +435,12 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band,
((band->qdelta_present && band->inherit_qdelta) || band->inherit_mv))
return AVERROR_INVALIDDATA;
+ 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 parameters %d\n",
+ tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size));
+ return AVERROR_INVALIDDATA;
+ }
+
/* scale factor for motion vectors */
mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
mv_x = mv_y = 0;
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index 5af7c91b63..e3b16e1ffb 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -493,8 +493,17 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
return 0;
}
-void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
- IVITile *tile, int32_t mv_scale)
+/**
+ * Handle empty tiles by performing data copying and motion
+ * compensation respectively.
+ *
+ * @param[in] avctx ptr to the AVCodecContext
+ * @param[in] band pointer to the band descriptor
+ * @param[in] tile pointer to the tile descriptor
+ * @param[in] mv_scale scaling factor for motion vectors
+ */
+static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
+ IVITile *tile, int32_t mv_scale)
{
int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;
int offs, mb_offset, row_offset;
@@ -504,6 +513,13 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch,
int mc_type);
+ 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 "
+ "parameters %d in ivi_process_empty_tile()\n",
+ tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size));
+ return AVERROR_INVALIDDATA;
+ }
+
offs = tile->ypos * band->pitch + tile->xpos;
mb = tile->mbs;
ref_mb = tile->ref_mbs;
@@ -584,6 +600,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
dst += band->pitch;
}
}
+
+ return 0;
}
@@ -698,8 +716,10 @@ static int decode_band(IVI45DecContext *ctx, int plane_num,
}
tile->is_empty = get_bits1(&ctx->gb);
if (tile->is_empty) {
- ff_ivi_process_empty_tile(avctx, band, tile,
+ result = ivi_process_empty_tile(avctx, band, tile,
(ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
+ if (result < 0)
+ break;
av_dlog(avctx, "Empty tile encountered!\n");
} else {
tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
@@ -764,6 +784,8 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
"Error while decoding picture header: %d\n", result);
return -1;
}
+ if (ctx->gop_invalid)
+ return AVERROR_INVALIDDATA;
if (ctx->gop_flags & IVI5_IS_PROTECTED) {
av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
@@ -803,6 +825,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
avctx->release_buffer(avctx, &ctx->frame);
ctx->frame.reference = 0;
+ avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return result;
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index 79895efed8..af99afc60a 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -248,6 +248,8 @@ typedef struct IVI45DecContext {
int (*decode_mb_info) (struct IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx);
void (*switch_buffers) (struct IVI45DecContext *ctx);
int (*is_nonnull_frame)(struct IVI45DecContext *ctx);
+
+ int gop_invalid;
} IVI45DecContext;
/** compare some properties of two pictures */
@@ -374,18 +376,6 @@ int ff_ivi_dec_tile_data_size(GetBitContext *gb);
int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile);
/**
- * Handle empty tiles by performing data copying and motion
- * compensation respectively.
- *
- * @param[in] avctx ptr to the AVCodecContext
- * @param[in] band pointer to the band descriptor
- * @param[in] tile pointer to the tile descriptor
- * @param[in] mv_scale scaling factor for motion vectors
- */
-void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
- IVITile *tile, int32_t mv_scale);
-
-/**
* Convert and output the current plane.
* This conversion is done by adding back the bias value of 128
* (subtracted in the encoder) and clipping the result.
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 729b9d0f88..22becdfc37 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -326,6 +326,11 @@ static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
output_zeros:
if (l->zeros_rem) {
count = FFMIN(l->zeros_rem, width - i);
+ if (end - dst < count) {
+ av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
memset(dst, 0, count);
l->zeros_rem -= count;
dst += count;
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index eccfb55432..a5255074d4 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -1166,7 +1166,12 @@ static int decode_subframe(WMAProDecodeCtx *s)
int num_bits = av_log2((s->subframe_len + 3)/4) + 1;
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
- s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
+ int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
+ if (num_vec_coeffs > WMAPRO_BLOCK_MAX_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
+ return AVERROR_INVALIDDATA;
+ }
+ s->channel[c].num_vec_coeffs = num_vec_coeffs;
}
} else {
for (i = 0; i < s->channels_for_cur_subframe; i++) {
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 72aa60731f..0a0ee013ba 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -1199,7 +1199,7 @@ resync:
}
ast->frame_offset += get_duration(ast, pkt->size);
}
- ast->remaining -= size;
+ ast->remaining -= err;
if(!ast->remaining){
avi->stream_index= -1;
ast->packet_size= 0;
diff --git a/libavformat/wav.c b/libavformat/wav.c
index ab4b3b42e7..9d4b0708b8 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -508,7 +508,7 @@ static int wav_read_header(AVFormatContext *s,
case MKTAG('L', 'I', 'S', 'T'):
list_type = avio_rl32(pb);
if (size < 4) {
- av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
+ av_log(s, AV_LOG_ERROR, "too short LIST");
return AVERROR_INVALIDDATA;
}
switch (list_type) {