From 3dde66752d59dfdd0f3727efd66e7202b3c75078 Mon Sep 17 00:00:00 2001 From: Jason Garrett-Glaser Date: Wed, 27 Oct 2010 16:30:01 +0000 Subject: [PATCH] Fix crashes in vorbis decoding found by zzuf Fixes issue 2322. Originally committed as revision 25591 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/vorbis_dec.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/libavcodec/vorbis_dec.c b/libavcodec/vorbis_dec.c index b44068fcdc..c209912cd1 100644 --- a/libavcodec/vorbis_dec.c +++ b/libavcodec/vorbis_dec.c @@ -61,8 +61,8 @@ typedef struct vorbis_floor0_s vorbis_floor0; typedef struct vorbis_floor1_s vorbis_floor1; struct vorbis_context_s; typedef -uint_fast8_t (* vorbis_floor_decode_func) - (struct vorbis_context_s *, vorbis_floor_data *, float *); +int (* vorbis_floor_decode_func) + (struct vorbis_context_s *, vorbis_floor_data *, float *); typedef struct { uint_fast8_t floor_type; vorbis_floor_decode_func decode; @@ -459,11 +459,11 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) // Process floors part -static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec); +static int vorbis_floor0_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec); static void create_map(vorbis_context *vc, uint_fast8_t floor_number); -static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec); +static int vorbis_floor1_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec); static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) { GetBitContext *gb = &vc->gb; @@ -1015,8 +1015,8 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) // Read and decode floor -static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec) +static int vorbis_floor0_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec) { vorbis_floor0 *vf = &vfu->t0; float *lsp = vf->lsp; @@ -1040,6 +1040,9 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, } AV_DEBUG("floor0 dec: booknumber: %u\n", book_idx); codebook = vc->codebooks[vf->book_list[book_idx]]; + /* Invalid codebook! */ + if (!codebook.codevectors) + return -1; while (lsp_lenorder) { int vec_off; @@ -1125,8 +1128,8 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, return 0; } -static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec) +static int vorbis_floor1_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec) { vorbis_floor1 *vf = &vfu->t1; GetBitContext *gb = &vc->gb; @@ -1502,13 +1505,20 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) for (i = 0; i < vc->audio_channels; ++i) { vorbis_floor *floor; + int ret; if (mapping->submaps > 1) { floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]]; } else { 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; }