Commit 4a71da0f authored by Mans Rullgard's avatar Mans Rullgard

cavs: fix some crashes with invalid bitstreams

This removes all valgrind-reported invalid writes with one
specific test file.

Fixes http://www.ocert.org/advisories/ocert-2011-002.htmlSigned-off-by: 's avatarMans Rullgard <mans@mansr.com>
parent 069083a4
...@@ -130,12 +130,14 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, ...@@ -130,12 +130,14 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb,
r++; r++;
mask = -(level_code & 1); mask = -(level_code & 1);
level = (level^mask) - mask; level = (level^mask) - mask;
} else { } else if (level_code >= 0) {
level = r->rltab[level_code][0]; level = r->rltab[level_code][0];
if(!level) //end of block signal if(!level) //end of block signal
break; break;
run = r->rltab[level_code][1]; run = r->rltab[level_code][1];
r += r->rltab[level_code][2]; r += r->rltab[level_code][2];
} else {
break;
} }
level_buf[i] = level; level_buf[i] = level;
run_buf[i] = run; run_buf[i] = run;
...@@ -189,7 +191,8 @@ static inline int decode_residual_inter(AVSContext *h) { ...@@ -189,7 +191,8 @@ static inline int decode_residual_inter(AVSContext *h) {
static int decode_mb_i(AVSContext *h, int cbp_code) { static int decode_mb_i(AVSContext *h, int cbp_code) {
GetBitContext *gb = &h->s.gb; GetBitContext *gb = &h->s.gb;
int block, pred_mode_uv; unsigned pred_mode_uv;
int block;
uint8_t top[18]; uint8_t top[18];
uint8_t *left = NULL; uint8_t *left = NULL;
uint8_t *d; uint8_t *d;
...@@ -445,6 +448,8 @@ static inline int check_for_slice(AVSContext *h) { ...@@ -445,6 +448,8 @@ static inline int check_for_slice(AVSContext *h) {
if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) { if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) {
skip_bits_long(gb,24+align); skip_bits_long(gb,24+align);
h->stc = get_bits(gb,8); h->stc = get_bits(gb,8);
if (h->stc >= h->mb_height)
return 0;
decode_slice_header(h,gb); decode_slice_header(h,gb);
return 1; return 1;
} }
...@@ -659,7 +664,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, ...@@ -659,7 +664,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
buf_end = buf + buf_size; buf_end = buf + buf_size;
for(;;) { for(;;) {
buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc); buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc);
if(stc & 0xFFFFFE00) if((stc & 0xFFFFFE00) || buf_ptr == buf_end)
return FFMAX(0, buf_ptr - buf - s->parse_context.last_index); return FFMAX(0, buf_ptr - buf - s->parse_context.last_index);
input_size = (buf_end - buf_ptr)*8; input_size = (buf_end - buf_ptr)*8;
switch(stc) { switch(stc) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment