summaryrefslogtreecommitdiff
path: root/libavcodec/wavpack.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-09-08 22:37:31 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-09-08 22:37:31 +0200
commit78d7d8fe9170f38ee0b2ab6f731ff1a61c712db5 (patch)
tree3fa4f47e3f1cca5a0cf39b42a5d171dec9a5b53f /libavcodec/wavpack.c
parent04c13dca8812e8302686887b6e8201d4ad25b7d8 (diff)
parent6376362d15ccbc02e15d0b3b7a7a5d862efd6b91 (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: Employ FF_ARRAY_ELEMS instead of manually calculating array length. Fixed invalid access in wavpack decoder on corrupted bitstream. Fixed invalid writes in wavpack decoder on corrupted bitstreams. Fixed invalid access in wavpack decoder on corrupted extra bits sub-blocks. rtpdec_asf: Fix integer underflow that could allow remote code execution Conflicts: libavformat/rtpdec_asf.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/wavpack.c')
-rw-r--r--libavcodec/wavpack.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 9da1f91d1d..870437d6f4 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -292,7 +292,14 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel
}
}else{
t = get_unary_0_33(gb);
- if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1));
+ if(t >= 2){
+ if(get_bits_left(gb) < t-1)
+ goto error;
+ t = get_bits(gb, t - 1) | (1 << (t-1));
+ }else{
+ if(get_bits_left(gb) < 0)
+ goto error;
+ }
ctx->zeroes = t;
if(ctx->zeroes){
memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median));
@@ -303,24 +310,24 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel
}
}
- if(get_bits_count(gb) >= ctx->data_size){
- *last = 1;
- return 0;
- }
-
if(ctx->zero){
t = 0;
ctx->zero = 0;
}else{
t = get_unary_0_33(gb);
- if(get_bits_count(gb) >= ctx->data_size){
- *last = 1;
- return 0;
- }
+ if(get_bits_left(gb) < 0)
+ goto error;
if(t == 16) {
t2 = get_unary_0_33(gb);
- if(t2 < 2) t += t2;
- else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1));
+ if(t2 < 2){
+ if(get_bits_left(gb) < 0)
+ goto error;
+ t += t2;
+ }else{
+ if(get_bits_left(gb) < t2 - 1)
+ goto error;
+ t += get_bits(gb, t2 - 1) | (1 << (t2 - 1));
+ }
}
if(ctx->one){
@@ -360,9 +367,13 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel
}
if(!c->error_limit){
ret = base + get_tail(gb, add);
+ if (get_bits_left(gb) <= 0)
+ goto error;
}else{
int mid = (base*2 + add + 1) >> 1;
while(add > c->error_limit){
+ if(get_bits_left(gb) <= 0)
+ goto error;
if(get_bits1(gb)){
add -= (mid - base);
base = mid;
@@ -376,6 +387,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel
if(ctx->hybrid_bitrate)
c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level);
return sign ? ~ret : ret;
+
+error:
+ *last = 1;
+ return 0;
}
static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, int S)
@@ -385,7 +400,7 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in
if(s->extra_bits){
S <<= s->extra_bits;
- if(s->got_extra_bits){
+ if(s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits){
S |= get_bits(&s->gb_extra_bits, s->extra_bits);
*crc = *crc * 9 + (S&0xffff) * 3 + ((unsigned)S>>16);
}
@@ -581,7 +596,10 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
count++;
}while(!last && count < s->max_samples);
- s->samples_left -= count;
+ if (last)
+ s->samples_left = 0;
+ else
+ s->samples_left -= count;
if(!s->samples_left){
wv_reset_saved_context(s);
if(crc != s->CRC){
@@ -659,7 +677,10 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
count++;
}while(!last && count < s->max_samples);
- s->samples_left -= count;
+ if (last)
+ s->samples_left = 0;
+ else
+ s->samples_left -= count;
if(!s->samples_left){
wv_reset_saved_context(s);
if(crc != s->CRC){
@@ -1114,7 +1135,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
int16_t *dst = (int16_t*)samples + 1;
int16_t *src = (int16_t*)samples;
int cnt = samplecount;
- while(cnt--){
+ while(cnt-- > 0){
*dst = *src;
src += channel_stride;
dst += channel_stride;
@@ -1123,7 +1144,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
int32_t *dst = (int32_t*)samples + 1;
int32_t *src = (int32_t*)samples;
int cnt = samplecount;
- while(cnt--){
+ while(cnt-- > 0){
*dst = *src;
src += channel_stride;
dst += channel_stride;
@@ -1132,7 +1153,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
float *dst = (float*)samples + 1;
float *src = (float*)samples;
int cnt = samplecount;
- while(cnt--){
+ while(cnt-- > 0){
*dst = *src;
src += channel_stride;
dst += channel_stride;