[FFmpeg-devel] [PATCH] avcodec: validate codec parameters in avcodec_parameters_to_context
Andreas Cadhalpun
andreas.cadhalpun at googlemail.com
Tue Oct 25 02:50:47 EEST 2016
This should reduce the impact of a demuxer (or API user) setting bogus
codec parameters.
Suggested-by: wm4
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun at googlemail.com>
---
libavcodec/utils.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 87de15f..9977ffd 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -4227,8 +4227,20 @@ int avcodec_parameters_to_context(AVCodecContext *codec,
codec->codec_id = par->codec_id;
codec->codec_tag = par->codec_tag;
+ if (par->bit_rate < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid bit rate %"PRId64"\n", par->bit_rate);
+ return AVERROR(EINVAL);
+ }
codec->bit_rate = par->bit_rate;
+ if (par->bits_per_coded_sample < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid bits per coded sample %d\n", par->bits_per_coded_sample);
+ return AVERROR(EINVAL);
+ }
codec->bits_per_coded_sample = par->bits_per_coded_sample;
+ if (par->bits_per_raw_sample < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid bits per raw sample %d\n", par->bits_per_raw_sample);
+ return AVERROR(EINVAL);
+ }
codec->bits_per_raw_sample = par->bits_per_raw_sample;
codec->profile = par->profile;
codec->level = par->level;
@@ -4236,42 +4248,110 @@ int avcodec_parameters_to_context(AVCodecContext *codec,
switch (par->codec_type) {
case AVMEDIA_TYPE_VIDEO:
codec->pix_fmt = par->format;
+ if ( (par->width || par->height) && av_image_check_size(par->width, par->height, 0, codec) < 0)
+ return AVERROR(EINVAL);
codec->width = par->width;
codec->height = par->height;
codec->field_order = par->field_order;
+ if (par->color_range < 0 || par->color_range > AVCOL_RANGE_NB) {
+ av_log(codec, AV_LOG_ERROR, "Invalid color range %d\n", par->color_range);
+ return AVERROR(EINVAL);
+ }
codec->color_range = par->color_range;
+ if (par->color_primaries < 0 || par->color_primaries > AVCOL_PRI_NB) {
+ av_log(codec, AV_LOG_ERROR, "Invalid color primaries %d\n", par->color_primaries);
+ return AVERROR(EINVAL);
+ }
codec->color_primaries = par->color_primaries;
+ if (par->color_trc < 0 || par->color_trc > AVCOL_TRC_NB) {
+ av_log(codec, AV_LOG_ERROR, "Invalid color transfer characteristics %d\n", par->color_trc);
+ return AVERROR(EINVAL);
+ }
codec->color_trc = par->color_trc;
+ if (par->color_space < 0 || par->color_space > AVCOL_SPC_NB) {
+ av_log(codec, AV_LOG_ERROR, "Invalid color space %d\n", par->color_space);
+ return AVERROR(EINVAL);
+ }
codec->colorspace = par->color_space;
+ if (par->chroma_location < 0 || par->chroma_location > AVCHROMA_LOC_NB) {
+ av_log(codec, AV_LOG_ERROR, "Invalid chroma location %d\n", par->chroma_location);
+ return AVERROR(EINVAL);
+ }
codec->chroma_sample_location = par->chroma_location;
+ if (par->sample_aspect_ratio.num < 0 || par->sample_aspect_ratio.den < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid sample aspect ratio %d/%d\n",
+ par->sample_aspect_ratio.num, par->sample_aspect_ratio.den);
+ return AVERROR(EINVAL);
+ }
codec->sample_aspect_ratio = par->sample_aspect_ratio;
+ if (par->video_delay < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid video delay %d\n", par->video_delay);
+ return AVERROR(EINVAL);
+ }
codec->has_b_frames = par->video_delay;
break;
case AVMEDIA_TYPE_AUDIO:
+ if (par->format < -1 || par->format > AV_SAMPLE_FMT_NB) {
+ av_log(codec, AV_LOG_ERROR, "Invalid sample format %d\n", par->format);
+ return AVERROR(EINVAL);
+ }
codec->sample_fmt = par->format;
codec->channel_layout = par->channel_layout;
+ if (par->channels < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid number of channels %d\n", par->channels);
+ return AVERROR(EINVAL);
+ }
codec->channels = par->channels;
+ if (par->sample_rate < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid sample rate %d\n", par->sample_rate);
+ return AVERROR(EINVAL);
+ }
codec->sample_rate = par->sample_rate;
+ if (par->block_align < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid block align %d\n", par->block_align);
+ return AVERROR(EINVAL);
+ }
codec->block_align = par->block_align;
+ if (par->frame_size < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid frame size %d\n", par->frame_size);
+ return AVERROR(EINVAL);
+ }
codec->frame_size = par->frame_size;
+ if (par->initial_padding < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid initial padding %d\n", par->initial_padding);
+ return AVERROR(EINVAL);
+ }
codec->delay =
codec->initial_padding = par->initial_padding;
+ if (par->trailing_padding < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid trailing padding %d\n", par->trailing_padding);
+ return AVERROR(EINVAL);
+ }
codec->trailing_padding = par->trailing_padding;
+ if (par->seek_preroll < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid seek preroll %d\n", par->seek_preroll);
+ return AVERROR(EINVAL);
+ }
codec->seek_preroll = par->seek_preroll;
break;
case AVMEDIA_TYPE_SUBTITLE:
+ if ((par->width || par->height) && av_image_check_size(par->width, par->height, 0, codec) < 0)
+ return AVERROR(EINVAL);
codec->width = par->width;
codec->height = par->height;
break;
}
- if (par->extradata) {
+ if (par->extradata_size > 0) {
av_freep(&codec->extradata);
codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!codec->extradata)
return AVERROR(ENOMEM);
memcpy(codec->extradata, par->extradata, par->extradata_size);
codec->extradata_size = par->extradata_size;
+ } else if (par->extradata_size < 0) {
+ av_log(codec, AV_LOG_ERROR, "Invalid extradata size %d", par->extradata_size);
+ return AVERROR(EINVAL);
}
return 0;
--
2.9.3
More information about the ffmpeg-devel
mailing list