aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Aimar <fenrir@videolan.org>2011-09-27 01:02:16 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-09-27 15:15:54 +0200
commit36bf135d4c32973933000a819208df7da9dd3e16 (patch)
tree1acf0d4a384a335a12868754a719b450c872ad9b
parent99d7d1510ed2e8dd73152a5dc1a5476faf1a7939 (diff)
downloadffmpeg-36bf135d4c32973933000a819208df7da9dd3e16.tar.gz
Check for various out of bound writes in the bink decoder.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/bink.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index e137312693..3c2148b3c6 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -344,14 +344,14 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *
memset(b->cur_dec, v, t);
b->cur_dec += t;
} else {
- do {
+ while (b->cur_dec < dec_end) {
v = GET_HUFF(gb, b->tree);
if (v) {
sign = -get_bits1(gb);
v = (v ^ sign) - sign;
}
*b->cur_dec++ = v;
- } while (b->cur_dec < dec_end);
+ }
}
return 0;
}
@@ -375,7 +375,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
memset(b->cur_dec, v, t);
b->cur_dec += t;
} else {
- do {
+ while (b->cur_dec < dec_end) {
v = GET_HUFF(gb, b->tree);
if (v < 12) {
last = v;
@@ -383,10 +383,12 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
} else {
int run = bink_rlelens[v - 12];
+ if (dec_end - b->cur_dec < run)
+ return -1;
memset(b->cur_dec, last, run);
b->cur_dec += run;
}
- } while (b->cur_dec < dec_end);
+ }
}
return 0;
}
@@ -457,6 +459,7 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
{
int i, j, len, len2, bsize, sign, v, v2;
int16_t *dst = (int16_t*)b->cur_dec;
+ int16_t *dst_end =( int16_t*)b->data_end;
CHECK_READ_VAL(gb, b, len);
v = get_bits(gb, start_bits - has_sign);
@@ -464,10 +467,14 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
sign = -get_bits1(gb);
v = (v ^ sign) - sign;
}
+ if (dst_end - dst < 1)
+ return -1;
*dst++ = v;
len--;
for (i = 0; i < len; i += 8) {
len2 = FFMIN(len - i, 8);
+ if (dst_end - dst < len2)
+ return -1;
bsize = get_bits(gb, 4);
if (bsize) {
for (j = 0; j < len2; j++) {
@@ -535,6 +542,8 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num)
int i, len;
CHECK_READ_VAL(gb, b, len);
+ if (b->data_end - b->cur_dec < len * (1 + (bits > 8)))
+ return -1;
if (bits <= 8) {
if (!issigned) {
for (i = 0; i < len; i++)