Mercurial > libavcodec.hg
changeset 1272:777d4145cdfb libavcodec
fix subtle logic problem in block unpacker that leads to incorrect token
decoding which leads to segfaults
author | tmmm |
---|---|
date | Mon, 19 May 2003 01:22:46 +0000 |
parents | 42ea05e4a391 |
children | a979fab41ed8 |
files | vp3.c |
diffstat | 1 files changed, 24 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/vp3.c Sun May 18 00:07:17 2003 +0000 +++ b/vp3.c Mon May 19 01:22:46 2003 +0000 @@ -1132,6 +1132,7 @@ int current_run = 0; int decode_fully_flags = 0; int decode_partial_blocks = 0; + int first_c_fragment_seen; int i, j; int current_fragment; @@ -1223,6 +1224,7 @@ s->coded_fragment_list_index = 0; s->first_coded_y_fragment = s->first_coded_c_fragment = 0; s->last_coded_y_fragment = s->last_coded_c_fragment = -1; + first_c_fragment_seen = 0; memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); for (i = 0; i < s->superblock_count; i++) { @@ -1253,15 +1255,18 @@ } if (bit) { - /* mode will be decoded in the next phase */ + /* default mode; actual mode will be decoded in + * the next phase */ s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; s->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->u_fragment_start) && - (s->last_coded_y_fragment == -1)) { + (s->last_coded_y_fragment == -1) && + (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; s->last_coded_y_fragment = s->first_coded_c_fragment - 1; + first_c_fragment_seen = 1; } s->coded_fragment_list_index++; s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; @@ -1286,9 +1291,11 @@ s->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->u_fragment_start) && - (s->last_coded_y_fragment == -1)) { + (s->last_coded_y_fragment == -1) && + (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; s->last_coded_y_fragment = s->first_coded_c_fragment - 1; + first_c_fragment_seen = 1; } s->coded_fragment_list_index++; s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; @@ -1299,11 +1306,13 @@ } } - if (s->first_coded_c_fragment == 0) - /* no C fragments coded */ + if (!first_c_fragment_seen) + /* only Y fragments coded in this frame */ s->last_coded_y_fragment = s->coded_fragment_list_index - 1; - else + else + /* end the list of coded fragments */ s->last_coded_c_fragment = s->coded_fragment_list_index - 1; + debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", s->coded_fragment_list_index, s->first_coded_y_fragment, @@ -1656,14 +1665,12 @@ DCTELEM coeff; Vp3Fragment *fragment; - if ((first_fragment < 0) || - (first_fragment >= s->fragment_count) || - (last_fragment < 0) || + if ((first_fragment >= s->fragment_count) || (last_fragment >= s->fragment_count)) { printf (" vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n", first_fragment, last_fragment); - return 1; + return 0; } for (i = first_fragment; i <= last_fragment; i++) { @@ -2433,6 +2440,11 @@ counter++; if (s->keyframe) { + + debug_vp3(", keyframe\n"); + /* skip the other 2 header bytes for now */ + skip_bits(&gb, 16); + if (s->last_frame.data[0] == s->golden_frame.data[0]) { if (s->golden_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); @@ -2458,22 +2470,16 @@ } else { + debug_vp3("\n"); + /* allocate a new current frame */ s->current_frame.reference = 0; if(avctx->get_buffer(avctx, &s->current_frame) < 0) { printf("vp3: get_buffer() failed\n"); return -1; } - } - if (s->keyframe) { - debug_vp3(", keyframe\n"); - /* skip the other 2 header bytes for now */ - skip_bits(&gb, 16); - } else - debug_vp3("\n"); - init_frame(s, &gb); #if KEYFRAMES_ONLY