diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-07-29 04:05:13 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-07-29 04:26:30 +0200 |
commit | 62d9d4d9d4bec0bfda26ba52899e9257288099b5 (patch) | |
tree | a4e4954fad4206ba2ca273f2303b6123c9dbd0d4 | |
parent | a3539d26eceebe69d890ad39e2ab0dcc19433246 (diff) | |
parent | e786cc33312083382f4ca394e67e1cb58c786289 (diff) | |
download | ffmpeg-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-- | Changelog | 29 | ||||
-rw-r--r-- | libavcodec/get_bits.h | 22 | ||||
-rw-r--r-- | libavcodec/ivi_common.c | 35 | ||||
-rw-r--r-- | libavcodec/kmvc.c | 26 | ||||
-rw-r--r-- | libavcodec/wmaprodec.c | 18 | ||||
-rw-r--r-- | libavformat/swfdec.c | 22 |
6 files changed, 102 insertions, 50 deletions
@@ -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); } } |