From b03761b1309293bbf30edef767503875277b01cf Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 00:52:36 -0400 Subject: libgsmdec: check output buffer size before decoding --- libavcodec/libgsm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'libavcodec/libgsm.c') diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 951e736098..6362f51ecb 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -168,18 +168,25 @@ static int libgsm_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int out_size = avctx->frame_size * av_get_bytes_per_sample(avctx->sample_fmt); + + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + *data_size = 0; /* In case of error */ if(buf_size < avctx->block_align) return -1; switch(avctx->codec_id) { case CODEC_ID_GSM: if(gsm_decode(avctx->priv_data,buf,data)) return -1; - *data_size = GSM_FRAME_SIZE*sizeof(int16_t); break; case CODEC_ID_GSM_MS: if(gsm_decode(avctx->priv_data,buf,data) || gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; - *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; } + + *data_size = out_size; return avctx->block_align; } -- cgit v1.2.1 From 9671db824565658154b638c97cfd3a9733117400 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 10:10:12 -0400 Subject: libgsmdec: do not needlessly set *data_size to 0 --- libavcodec/libgsm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libavcodec/libgsm.c') diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 6362f51ecb..790eacd6dd 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -175,7 +175,6 @@ static int libgsm_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } - *data_size = 0; /* In case of error */ if(buf_size < avctx->block_align) return -1; switch(avctx->codec_id) { case CODEC_ID_GSM: -- cgit v1.2.1 From 9d52f0a7113d9ce14e038f8e65fd0e92ce0d33c1 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 10:18:07 -0400 Subject: gsm: log error message when packet is too small --- libavcodec/libgsm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'libavcodec/libgsm.c') diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 790eacd6dd..1b12ca45e6 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -175,7 +175,11 @@ static int libgsm_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } - if(buf_size < avctx->block_align) return -1; + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + switch(avctx->codec_id) { case CODEC_ID_GSM: if(gsm_decode(avctx->priv_data,buf,data)) return -1; -- cgit v1.2.1 From 480324e7ca0b87105fd7ee168292a0d5692af128 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 10:28:41 -0400 Subject: libgsm: simplify decoding by using a loop --- libavcodec/libgsm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'libavcodec/libgsm.c') diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 1b12ca45e6..bca7bfbe97 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -166,8 +166,11 @@ static av_cold int libgsm_decode_close(AVCodecContext *avctx) { static int libgsm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { + int i, ret; + struct gsm_state *s = avctx->priv_data; uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int16_t *samples = data; int out_size = avctx->frame_size * av_get_bytes_per_sample(avctx->sample_fmt); if (*data_size < out_size) { @@ -180,13 +183,11 @@ static int libgsm_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - switch(avctx->codec_id) { - case CODEC_ID_GSM: - if(gsm_decode(avctx->priv_data,buf,data)) return -1; - break; - case CODEC_ID_GSM_MS: - if(gsm_decode(avctx->priv_data,buf,data) || - gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; + for (i = 0; i < avctx->frame_size / GSM_FRAME_SIZE; i++) { + if ((ret = gsm_decode(s, buf, samples)) < 0) + return -1; + buf += GSM_BLOCK_SIZE; + samples += GSM_FRAME_SIZE; } *data_size = out_size; -- cgit v1.2.1 From 20e081dddcffa6eec459d695f3850796d1bdd7f7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 10:35:15 -0400 Subject: libgsm: add flush function to reset the decoder state when seeking --- libavcodec/libgsm.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'libavcodec/libgsm.c') diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index bca7bfbe97..c02594d0d6 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -194,6 +194,11 @@ static int libgsm_decode_frame(AVCodecContext *avctx, return avctx->block_align; } +static void libgsm_flush(AVCodecContext *avctx) { + gsm_destroy(avctx->priv_data); + avctx->priv_data = gsm_create(); +} + AVCodec ff_libgsm_decoder = { .name = "libgsm", .type = AVMEDIA_TYPE_AUDIO, @@ -201,6 +206,7 @@ AVCodec ff_libgsm_decoder = { .init = libgsm_decode_init, .close = libgsm_decode_close, .decode = libgsm_decode_frame, + .flush = libgsm_flush, .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), }; @@ -211,5 +217,6 @@ AVCodec ff_libgsm_ms_decoder = { .init = libgsm_decode_init, .close = libgsm_decode_close, .decode = libgsm_decode_frame, + .flush = libgsm_flush, .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), }; -- cgit v1.2.1