[FFmpeg-cvslog] Fixed invalid access in wavpack decoder on corrupted bitstream.
Laurent Aimar
git at videolan.org
Sun Dec 25 01:35:59 CET 2011
ffmpeg | branch: release/0.6 | Laurent Aimar <fenrir at videolan.org> | Wed Sep 7 22:02:55 2011 +0200| [1edc513bcf78341b4614081812cc7b66cd84b465] | committer: Reinhard Tartler
Fixed invalid access in wavpack decoder on corrupted bitstream.
Signed-off-by: Martin Storsjö <martin at martin.st>
(cherry picked from commit 55354b7de21e7bb4bbeb1c12ff55ea17f807c70c)
Signed-off-by: Anton Khirnov <anton at khirnov.net>
(cherry picked from commit 4b84e995ad88f3bfa533c38218f2791c14fd72f0)
Signed-off-by: Reinhard Tartler <siretart at tauware.de>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1edc513bcf78341b4614081812cc7b66cd84b465
---
libavcodec/wavpack.c | 49 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 3963a60..906ccea 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -275,7 +275,14 @@ static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int channel, int
}
}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));
@@ -286,24 +293,24 @@ static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int channel, int
}
}
- 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){
@@ -343,9 +350,13 @@ static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int channel, int
}
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;
@@ -359,6 +370,10 @@ static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int channel, int
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(WavpackContext *s, uint32_t *crc, int S)
@@ -559,7 +574,10 @@ static inline int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, void *d
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");
@@ -632,7 +650,10 @@ static inline int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, void *dst
count++;
}while(!last && count < s->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");
More information about the ffmpeg-cvslog
mailing list