summaryrefslogtreecommitdiff
path: root/libavcodec/utils.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2013-10-27 09:56:00 +0100
committerAnton Khirnov <anton@khirnov.net>2013-10-30 08:43:03 +0100
commitb9589f5a770ec2357ab7920a5fabe8510b8601f9 (patch)
tree2f84c3559eb8451f693766a76f585475057af27a /libavcodec/utils.c
parent5c0a09839c707f10e5dba59460e219e989c1da93 (diff)
lavc: add error checking to apply_param_change.
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r--libavcodec/utils.c51
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);