diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-06-04 13:05:25 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-06-04 13:05:25 +0200 |
commit | 64bc5f3bf75f6f009b66ba113da4afd1e7625d22 (patch) | |
tree | 1d484f27ebfccbf1f96495081dfab68938b53184 | |
parent | 4169912f3969f9207c3a5fefdf1b7a4185edb1c8 (diff) | |
parent | b61e311b0eeabaab8eb05f4e5e5c6c8c9d84f3cf (diff) | |
download | ffmpeg-64bc5f3bf75f6f009b66ba113da4afd1e7625d22.tar.gz |
Merge remote-tracking branch 'qatar/release/0.7' into release/0.8
* qatar/release/0.7:
Update RELEASE file for 0.7.6
Update changelog for 0.7.6 release
ea: check chunk_size for validity.
png: check bit depth for PAL8/Y400A pixel formats.
x86: fix build with gcc 4.7
qdm2: clip array indices returned by qdm2_get_vlc().
kmvc: Check palsize.
aacsbr: prevent out of bounds memcpy().
rtpdec_asf: Fix integer underflow that could allow remote code execution
dpcm: ignore extra unpaired bytes in stereo streams.
tqi: Pass errors from the MB decoder
h264: Add check for invalid chroma_format_idc
adpcm: ADPCM Electronic Arts has always two channels
h263dec: Disallow width/height changing with frame threads.
vqavideo: return error if image size is not a multiple of block size
celp filters: Do not read earlier than the start of the 'out' vector.
motionpixels: Clip YUV values after applying a gradient.
h263: more strictly forbid frame size changes with frame-mt.
h264: additional protection against unsupported size/bitdepth changes.
Conflicts:
Changelog
RELEASE
libavcodec/aacsbr.c
libavcodec/h264_ps.c
libavcodec/pngdec.c
libavformat/rtpdec_asf.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/aacsbr.c | 7 | ||||
-rw-r--r-- | libavcodec/adpcm.c | 10 | ||||
-rw-r--r-- | libavcodec/celp_filters.c | 4 | ||||
-rw-r--r-- | libavcodec/dpcm.c | 6 | ||||
-rw-r--r-- | libavcodec/eatqi.c | 10 | ||||
-rw-r--r-- | libavcodec/h263dec.c | 7 | ||||
-rw-r--r-- | libavcodec/h264.c | 4 | ||||
-rw-r--r-- | libavcodec/h264_ps.c | 7 | ||||
-rw-r--r-- | libavcodec/kmvc.c | 7 | ||||
-rw-r--r-- | libavcodec/motionpixels.c | 6 | ||||
-rw-r--r-- | libavcodec/pngdec.c | 5 | ||||
-rw-r--r-- | libavcodec/qdm2.c | 18 | ||||
-rw-r--r-- | libavcodec/vqavideo.c | 6 | ||||
-rw-r--r-- | libavformat/electronicarts.c | 7 | ||||
-rw-r--r-- | libavformat/rtpdec_asf.c | 12 |
15 files changed, 86 insertions, 30 deletions
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 866482aac3..d7a95e86f4 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -1183,14 +1183,15 @@ static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct, { int i, n; const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us; + const int step = 128 >> div; float *v; for (i = 0; i < 32; i++) { - if (*v_off < 128 >> div) { + if (*v_off < step) { int saved_samples = (1280 - 128) >> div; memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float)); - *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - (128 >> div); + *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step; } else { - *v_off -= 128 >> div; + *v_off -= step; } v = v0 + *v_off; if (div) { diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 8fa6d91082..6ea600a88f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -778,9 +778,13 @@ static int adpcm_encode_frame(AVCodecContext *avctx, static av_cold int adpcm_decode_init(AVCodecContext * avctx) { ADPCMContext *c = avctx->priv_data; + unsigned int min_channels = 1; unsigned int max_channels = 2; switch(avctx->codec->id) { + case CODEC_ID_ADPCM_EA: + min_channels = 2; + break; case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: @@ -788,8 +792,10 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) max_channels = 6; break; } - if(avctx->channels > max_channels){ - return -1; + + if (avctx->channels < min_channels || avctx->channels > max_channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR(EINVAL); } switch(avctx->codec->id) { diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c index 8b68c2ffef..229d7576ea 100644 --- a/libavcodec/celp_filters.c +++ b/libavcodec/celp_filters.c @@ -133,9 +133,8 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, out2 -= val * old_out2; out3 -= val * old_out3; - old_out3 = out[-5]; - for (i = 5; i <= filter_length; i += 2) { + old_out3 = out[-i]; val = filter_coeffs[i-1]; out0 -= val * old_out3; @@ -154,7 +153,6 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, FFSWAP(float, old_out0, old_out2); old_out1 = old_out3; - old_out3 = out[-i-2]; } tmp0 = out0; diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index ee8eb6a722..947e1cb31e 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -169,6 +169,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, int in, out = 0; int predictor[2]; int channel_number = 0; + int stereo = s->channels - 1; short *output_samples = data; int shift[2]; unsigned char byte; @@ -177,6 +178,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, if (!buf_size) return 0; + if (stereo && (buf_size & 1)) + buf_size--; + // almost every DPCM variant expands one byte of data into two if(*data_size/2 < buf_size) return -1; @@ -295,7 +299,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, } *data_size = out * sizeof(short); - return buf_size; + return avpkt->size; } #define DPCM_DECODER(id, name, long_name_) \ diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 44792f0483..09992f5611 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -59,12 +59,15 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx) return 0; } -static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) +static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) { int n; s->dsp.clear_blocks(block[0]); for (n=0; n<6; n++) - ff_mpeg1_decode_block_intra(s, block[n], n); + if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0) + return -1; + + return 0; } static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64]) @@ -136,7 +139,8 @@ static int tqi_decode_frame(AVCodecContext *avctx, for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++) { - tqi_decode_mb(s, t->block); + if (tqi_decode_mb(s, t->block) < 0) + break; tqi_idct_put(t, t->block); } diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 96422ef491..8a9cb800f1 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -438,6 +438,13 @@ retry: if (ret < 0){ av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return -1; + } else if ((s->width != avctx->coded_width || + s->height != avctx->coded_height || + (s->width + 15) >> 4 != s->mb_width || + (s->height + 15) >> 4 != s->mb_height) && + (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding } avctx->has_b_frames= !s->low_delay; diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 462fae2a98..d332f1dbf7 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2620,9 +2620,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if (s->context_initialized && ( s->width != s->avctx->width || s->height != s->avctx->height || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) { - if(h != h0) { + if(h != h0 || (HAVE_THREADS && h->s.avctx->active_thread_type & FF_THREAD_FRAME)) { av_log_missing_feature(s->avctx, "Width/height changing with threads is", 0); - return -1; // width / height changed during parallelized decoding + return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding } free_tables(h, 0); flush_dpb(s->avctx); diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 65d856a98a..2b30e45483 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -345,9 +345,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ if (sps->chroma_format_idc > 3U) { av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc); goto fail; - } - if(sps->chroma_format_idc == 3) + } else if(sps->chroma_format_idc == 3) { sps->residual_color_transform_flag = get_bits1(&s->gb); + } sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) { @@ -490,6 +490,9 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ if(pps_id >= MAX_PPS_COUNT) { av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); return -1; + } else if (h->sps.bit_depth_luma > 10) { + av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma); + return AVERROR_PATCHWELCOME; } pps= av_mallocz(sizeof(PPS)); diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 3681575daa..6764fad5f1 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -33,6 +33,7 @@ #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 #define KMVC_METHOD 0x0F +#define MAX_PALSIZE 256 /* * Decoder context @@ -43,7 +44,7 @@ typedef struct KmvcContext { int setpal; int palsize; - uint32_t pal[256]; + uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; uint8_t *frm0, *frm1; } KmvcContext; @@ -414,6 +415,10 @@ static av_cold int decode_init(AVCodecContext * avctx) c->palsize = 127; } else { c->palsize = AV_RL16(avctx->extradata + 10); + if (c->palsize >= MAX_PALSIZE) { + av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n"); + return AVERROR_INVALIDDATA; + } } if (avctx->extradata_size == 1036) { // palette in extradata diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index 635a7d14a1..aa398c9592 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -191,10 +191,13 @@ static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) p = mp_get_yuv_from_rgb(mp, x - 1, y); } else { p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y = av_clip(p.y, 0, 31); if ((x & 3) == 0) { if ((y & 3) == 0) { p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v = av_clip(p.v, -32, 31); p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u = av_clip(p.u, -32, 31); mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p; } else { p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v; @@ -218,9 +221,12 @@ static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) p = mp_get_yuv_from_rgb(mp, 0, y); } else { p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y = av_clip(p.y, 0, 31); if ((y & 3) == 0) { p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v = av_clip(p.v, -32, 31); p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u = av_clip(p.u, -32, 31); } mp->vpt[y] = p; mp_set_rgb_from_yuv(mp, 0, y, &p); diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index f8ebb1b02d..3c6284fc10 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -469,11 +469,12 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = PIX_FMT_RGB48BE; } else if (s->bit_depth == 1) { avctx->pix_fmt = PIX_FMT_MONOBLACK; - } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = PIX_FMT_PAL8; } else if (s->bit_depth == 8 && s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - avctx->pix_fmt = PIX_FMT_GRAY8A; + avctx->pix_fmt = PIX_FMT_Y400A; } else { goto fail; } diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 06bebb13bb..e237157f48 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -881,9 +881,13 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l break; case 30: - if (BITS_LEFT(length,gb) >= 4) - samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)]; - else + if (BITS_LEFT(length,gb) >= 4) { + unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1); + if (index < FF_ARRAY_ELEMS(type30_dequant)) { + samples[0] = type30_dequant[index]; + } else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + } else samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); run = 1; @@ -897,8 +901,12 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l type34_predictor = samples[0]; type34_first = 0; } else { - samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor; - type34_predictor = samples[0]; + unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1); + if (index < FF_ARRAY_ELEMS(type34_delta)) { + samples[0] = type34_delta[index] / type34_div + type34_predictor; + type34_predictor = samples[0]; + } else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); } } else { samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 64a68e1ca1..d1eab5bfa1 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -159,6 +159,12 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) return -1; } + if (s->width & (s->vector_width - 1) || + s->height & (s->vector_height - 1)) { + av_log(avctx, AV_LOG_ERROR, "Image size not multiple of block size\n"); + return AVERROR_INVALIDDATA; + } + /* allocate codebooks */ s->codebook_size = MAX_CODEBOOK_SIZE; s->codebook = av_malloc(s->codebook_size); diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 0b882aac87..8e44fadb55 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -470,12 +470,17 @@ static int ea_read_packet(AVFormatContext *s, while (!packet_read) { chunk_type = avio_rl32(pb); - chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; + chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); + if (chunk_size <= 8) + return AVERROR_INVALIDDATA; + chunk_size -= 8; switch (chunk_type) { /* audio data */ case ISNh_TAG: /* header chunk also contains data; skip over the header portion*/ + if (chunk_size < 32) + return AVERROR_INVALIDDATA; avio_skip(pb, 32); chunk_size -= 32; case ISNd_TAG: diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c index 643ea7a5a0..d97e8ee918 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -233,14 +233,16 @@ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf, int cur_len = start_off + len_off - off; int prev_len = out_len; - void *newbuf; + void *newmem; + out_len += cur_len; - if(FFMIN(cur_len, len - off)<0) + + if (FFMIN(cur_len, len - off) < 0) return -1; - newbuf = av_realloc(asf->buf, out_len); - if(!newbuf) + newmem = av_realloc(asf->buf, out_len); + if (!newmem) return -1; - asf->buf= newbuf; + asf->buf = newmem; memcpy(asf->buf + prev_len, buf + off, FFMIN(cur_len, len - off)); avio_skip(pb, cur_len); |