diff options
author | Anton Khirnov <anton@khirnov.net> | 2013-10-27 09:56:00 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2013-10-30 08:43:03 +0100 |
commit | b9589f5a770ec2357ab7920a5fabe8510b8601f9 (patch) | |
tree | 2f84c3559eb8451f693766a76f585475057af27a /libavcodec/utils.c | |
parent | 5c0a09839c707f10e5dba59460e219e989c1da93 (diff) | |
download | ffmpeg-b9589f5a770ec2357ab7920a5fabe8510b8601f9.tar.gz |
lavc: add error checking to apply_param_change.
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 9ef477f429..d14d4f4472 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1321,46 +1321,59 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } -static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) +static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { int size = 0; const uint8_t *data; uint32_t flags; - if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) - return; - data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); - if (!data || size < 4) - return; + if (!data) + return 0; + + if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + return AVERROR(EINVAL); + } + + if (size < 4) + goto fail; + flags = bytestream_get_le32(&data); size -= 4; - if (size < 4) /* Required for any of the changes */ - return; + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; avctx->channels = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { if (size < 8) - return; + goto fail; avctx->channel_layout = bytestream_get_le64(&data); size -= 8; } - if (size < 4) - return; if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; avctx->sample_rate = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { if (size < 8) - return; + goto fail; avctx->width = bytestream_get_le32(&data); avctx->height = bytestream_get_le32(&data); avcodec_set_dimensions(avctx, avctx->width, avctx->height); size -= 8; } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + return AVERROR_INVALIDDATA; } int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, @@ -1375,7 +1388,12 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi return -1; avctx->pkt = avpkt; - apply_param_change(avctx, avpkt); + ret = apply_param_change(avctx, avpkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } avcodec_get_frame_defaults(picture); @@ -1441,7 +1459,12 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, return AVERROR(EINVAL); } - apply_param_change(avctx, avpkt); + ret = apply_param_change(avctx, avpkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } avcodec_get_frame_defaults(frame); |