Fix crashes in vorbis decoding found by zzuf

Fixes issue 2322.

Originally committed as revision 25591 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Jason Garrett-Glaser 2010-10-27 16:30:01 +00:00
parent b11b72a65f
commit 3dde66752d
1 changed files with 21 additions and 11 deletions

View File

@ -61,7 +61,7 @@ typedef struct vorbis_floor0_s vorbis_floor0;
typedef struct vorbis_floor1_s vorbis_floor1; typedef struct vorbis_floor1_s vorbis_floor1;
struct vorbis_context_s; struct vorbis_context_s;
typedef typedef
uint_fast8_t (* vorbis_floor_decode_func) int (* vorbis_floor_decode_func)
(struct vorbis_context_s *, vorbis_floor_data *, float *); (struct vorbis_context_s *, vorbis_floor_data *, float *);
typedef struct { typedef struct {
uint_fast8_t floor_type; uint_fast8_t floor_type;
@ -459,10 +459,10 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc)
// Process floors part // Process floors part
static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, static int vorbis_floor0_decode(vorbis_context *vc,
vorbis_floor_data *vfu, float *vec); vorbis_floor_data *vfu, float *vec);
static void create_map(vorbis_context *vc, uint_fast8_t floor_number); static void create_map(vorbis_context *vc, uint_fast8_t floor_number);
static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, static int vorbis_floor1_decode(vorbis_context *vc,
vorbis_floor_data *vfu, float *vec); vorbis_floor_data *vfu, float *vec);
static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
{ {
@ -1015,7 +1015,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
// Read and decode floor // Read and decode floor
static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, static int vorbis_floor0_decode(vorbis_context *vc,
vorbis_floor_data *vfu, float *vec) vorbis_floor_data *vfu, float *vec)
{ {
vorbis_floor0 *vf = &vfu->t0; vorbis_floor0 *vf = &vfu->t0;
@ -1040,6 +1040,9 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc,
} }
AV_DEBUG("floor0 dec: booknumber: %u\n", book_idx); AV_DEBUG("floor0 dec: booknumber: %u\n", book_idx);
codebook = vc->codebooks[vf->book_list[book_idx]]; codebook = vc->codebooks[vf->book_list[book_idx]];
/* Invalid codebook! */
if (!codebook.codevectors)
return -1;
while (lsp_len<vf->order) { while (lsp_len<vf->order) {
int vec_off; int vec_off;
@ -1125,7 +1128,7 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc,
return 0; return 0;
} }
static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, static int vorbis_floor1_decode(vorbis_context *vc,
vorbis_floor_data *vfu, float *vec) vorbis_floor_data *vfu, float *vec)
{ {
vorbis_floor1 *vf = &vfu->t1; vorbis_floor1 *vf = &vfu->t1;
@ -1502,13 +1505,20 @@ static int vorbis_parse_audio_packet(vorbis_context *vc)
for (i = 0; i < vc->audio_channels; ++i) { for (i = 0; i < vc->audio_channels; ++i) {
vorbis_floor *floor; vorbis_floor *floor;
int ret;
if (mapping->submaps > 1) { if (mapping->submaps > 1) {
floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]]; floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]];
} else { } else {
floor = &vc->floors[mapping->submap_floor[0]]; floor = &vc->floors[mapping->submap_floor[0]];
} }
no_residue[i] = floor->decode(vc, &floor->data, ch_floor_ptr); ret = floor->decode(vc, &floor->data, ch_floor_ptr);
if (ret < 0) {
av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
return -1;
}
no_residue[i] = ret;
ch_floor_ptr += blocksize / 2; ch_floor_ptr += blocksize / 2;
} }