summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-07-29 04:05:13 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-07-29 04:26:30 +0200
commit62d9d4d9d4bec0bfda26ba52899e9257288099b5 (patch)
treea4e4954fad4206ba2ca273f2303b6123c9dbd0d4
parenta3539d26eceebe69d890ad39e2ab0dcc19433246 (diff)
parente786cc33312083382f4ca394e67e1cb58c786289 (diff)
downloadffmpeg-62d9d4d9d4bec0bfda26ba52899e9257288099b5.tar.gz
Merge remote-tracking branch 'qatar/release/0.8' into release/0.10
* qatar/release/0.8: swfdec: do better validation of tag length Changelog for 0.8.8 kmvc: Clip pixel position to valid range kmvc: use fixed sized arrays in the context indeo: use a typedef for the mc function pointer lavc: check for overflow in init_get_bits indeo: check for reference when inheriting mvs indeo: use proper error code indeo: Properly forward the error codes wmapro: error out on impossible scale factor offsets wmapro: check the min_samples_per_subframe wmapro: return early on unsupported condition wmapro: check num_vec_coeffs against the actual available buffer Conflicts: Changelog libavformat/swfdec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--Changelog29
-rw-r--r--libavcodec/get_bits.h22
-rw-r--r--libavcodec/ivi_common.c35
-rw-r--r--libavcodec/kmvc.c26
-rw-r--r--libavcodec/wmaprodec.c18
-rw-r--r--libavformat/swfdec.c22
6 files changed, 102 insertions, 50 deletions
diff --git a/Changelog b/Changelog
index bbb2850f96..f4238a7c87 100644
--- a/Changelog
+++ b/Changelog
@@ -5,7 +5,34 @@ version next:
version 0.10.8
-
+- kmvc: Clip pixel position to valid range
+- kmvc: use fixed sized arrays in the context
+- indeo: use a typedef for the mc function pointer
+- lavc: check for overflow in init_get_bits
+- mjpegdec: properly report unsupported disabled features
+- jpegls: return meaningful errors
+- jpegls: factorize return paths
+- jpegls: check the scan offset
+- wavpack: validate samples size parsed in wavpack_decode_block
+- ljpeg: use the correct number of components in yuv
+- mjpeg: Validate sampling factors
+- mjpegdec: validate parameters in mjpeg_decode_scan_progressive_ac
+- wavpack: check packet size early
+- wavpack: return meaningful errors
+- apetag: use int64_t for filesize
+- tiff: do not overread the source buffer
+- Prepare for 0.8.8 Release
+- smacker: fix an off by one in huff.length computation
+- smacker: check the return value of smacker_decode_tree
+- smacker: pad the extradata allocation
+- smacker: check frame size validity
+- vmdav: convert to bytestream2
+- 4xm: don't rely on get_buffer() initializing the frame.
+- 4xm: check the return value of read_huffman_tables().
+- 4xm: use the correct logging context
+- 4xm: reject frames not compatible with the declared version
+- 4xm: check bitstream_size boundary before using it
+- 4xm: do not overread the source buffer in decode_p_block
- avfiltergraph: check for sws opts being non-NULL before using them
- bmv: check for len being valid in bmv_decode_frame()
- dfa: check for invalid access in decode_wdlt()
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index 09b846eb42..afa4f2ac44 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -342,25 +342,33 @@ 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;
s->size_in_bits_plus8 = bit_size + 8;
s->buffer_end = buffer + buffer_size;
s->index = 0;
+ return ret;
}
static inline void align_get_bits(GetBitContext *s)
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index ff954cd452..3bf9455411 100644
--- a/libavcodec/ivi_common.c
+++ b/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])
@@ -345,8 +348,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;
@@ -435,7 +437,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];
@@ -458,7 +460,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) {
@@ -516,8 +518,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 "
@@ -739,8 +740,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;
}
@@ -788,14 +797,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);
@@ -806,10 +815,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/libavcodec/kmvc.c b/libavcodec/kmvc.c
index 6360b494f2..4fc50fa761 100644
--- a/libavcodec/kmvc.c
+++ b/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;
@@ -403,30 +403,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/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 53bce957df..e4309ad975 100644
--- a/libavcodec/wmaprodec.c
+++ b/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;
}
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index fbdb4ac645..af93673a5f 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -91,6 +91,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
tag = get_swf_tag(pb, &len);
if (tag < 0)
return tag;
+ if (len < 0) {
+ av_log(s, AV_LOG_ERROR, "invalid tag length: %d\n", len);
+ return AVERROR_INVALIDDATA;
+ }
if (tag == TAG_VIDEOSTREAM) {
int ch_id = avio_rl16(pb);
len -= 2;
@@ -150,7 +154,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
st = s->streams[i];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) {
frame = avio_rl16(pb);
- if ((res = av_get_packet(pb, pkt, len-2)) < 0)
+ len -= 2;
+ if (len <= 0)
+ goto skip;
+ if ((res = av_get_packet(pb, pkt, len)) < 0)
return res;
pkt->pos = pos;
pkt->pts = frame;
@@ -164,9 +171,14 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) {
if (st->codec->codec_id == CODEC_ID_MP3) {
avio_skip(pb, 4);
- if ((res = av_get_packet(pb, pkt, len-4)) < 0)
+ len -= 4;
+ if (len <= 0)
+ goto skip;
+ if ((res = av_get_packet(pb, pkt, len)) < 0)
return res;
} else { // ADPCM, PCM
+ if (len <= 0)
+ goto skip;
if ((res = av_get_packet(pb, pkt, len)) < 0)
return res;
}
@@ -193,7 +205,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
st = vst;
}
avio_rl16(pb); /* BITMAP_ID */
- if ((res = av_new_packet(pkt, len-2)) < 0)
+ len -= 2;
+ if (len < 4)
+ goto skip;
+ if ((res = av_new_packet(pkt, len)) < 0)
return res;
avio_read(pb, pkt->data, 4);
if (AV_RB32(pkt->data) == 0xffd8ffd9 ||
@@ -210,6 +225,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
return pkt->size;
}
skip:
+ len = FFMAX(0, len);
avio_skip(pb, len);
}
}