diff options
author | Jason Garrett-Glaser <darkshikari@gmail.com> | 2010-10-27 16:30:01 +0000 |
---|---|---|
committer | Jason Garrett-Glaser <darkshikari@gmail.com> | 2010-10-27 16:30:01 +0000 |
commit | 3dde66752d59dfdd0f3727efd66e7202b3c75078 (patch) | |
tree | 4be7cd90c731d7eb996046947187825ef7b58485 | |
parent | b11b72a65f213055e6340d00aaed62a8a8821206 (diff) | |
download | ffmpeg-3dde66752d59dfdd0f3727efd66e7202b3c75078.tar.gz |
Fix crashes in vorbis decoding found by zzuf
Fixes issue 2322.
Originally committed as revision 25591 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/vorbis_dec.c | 32 |
1 files 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_len<vf->order) { 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; } |