This should reduce the impact of a demuxer (or API user) setting bogus codec parameters.
Suggested-by: wm4 Signed-off-by: Andreas Cadhalpun <andreas.cadhal...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel