2011-09-21 04:58:48 -04:00
|
|
|
$OpenBSD: patch-libavcodec_wavpack_c,v 1.2 2011/09/21 08:58:48 sthen Exp $
|
2011-09-12 17:04:48 -04:00
|
|
|
|
|
|
|
- Fixed invalid access with corrupted extra bits sub-blocks.
|
|
|
|
- Fixed invalid writes with corrupted bitstreams.
|
|
|
|
- Fixed invalid access with corrupted bitstream.
|
|
|
|
|
2011-09-21 04:58:48 -04:00
|
|
|
--- libavcodec/wavpack.c.orig Mon Mar 28 19:23:17 2011
|
|
|
|
+++ libavcodec/wavpack.c Mon Sep 12 03:06:17 2011
|
2011-09-12 17:04:48 -04:00
|
|
|
@@ -292,7 +292,14 @@ static int wv_get_value(WavpackFrameContext *ctx, GetB
|
|
|
|
}
|
|
|
|
}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, GetB
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- 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, GetB
|
|
|
|
}
|
|
|
|
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, GetB
|
|
|
|
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(WavpackFrameCon
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
@@ -580,7 +595,10 @@ static inline int wv_unpack_stereo(WavpackFrameContext
|
|
|
|
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){
|
|
|
|
if(crc != s->CRC){
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
|
|
|
|
@@ -658,7 +676,10 @@ static inline int wv_unpack_mono(WavpackFrameContext *
|
|
|
|
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){
|
|
|
|
if(crc != s->CRC){
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
|
2011-09-21 04:58:48 -04:00
|
|
|
@@ -1098,6 +1119,10 @@ static int wavpack_decode_block(AVCodecContext *avctx,
|
|
|
|
samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S32);
|
|
|
|
else
|
|
|
|
samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT);
|
|
|
|
+
|
|
|
|
+ if (samplecount < 0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
samplecount >>= 1;
|
|
|
|
}else{
|
|
|
|
const int channel_stride = avctx->channels;
|
|
|
|
@@ -1108,6 +1133,9 @@ static int wavpack_decode_block(AVCodecContext *avctx,
|
|
|
|
samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S32);
|
|
|
|
else
|
|
|
|
samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT);
|
|
|
|
+
|
|
|
|
+ if (samplecount < 0)
|
|
|
|
+ return -1;
|
|
|
|
|
|
|
|
if(s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16){
|
2011-09-12 17:04:48 -04:00
|
|
|
int16_t *dst = (int16_t*)samples + 1;
|