From c3f87f7545d42520921bc448b9fbd7324c574e49 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 4 Jun 2015 03:47:55 +0200 Subject: swresample/swresample: Cleanup on init failure. This avoids leaks if the user doest call swr_close() after a failed init Found-by: James Almer Reviewed-by: James Almer Signed-off-by: Michael Niedermayer --- libswresample/swresample.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'libswresample') diff --git a/libswresample/swresample.c b/libswresample/swresample.c index 4aa081be1b..9ab29d6f79 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -266,7 +266,8 @@ av_cold int swr_init(struct SwrContext *s){ && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP && s->resample){ av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16/s32/flt/dbl\n"); - return -1; + ret = AVERROR(EINVAL); + goto fail; } #define RSC 1 //FIXME finetune @@ -280,24 +281,28 @@ av_cold int swr_init(struct SwrContext *s){ if(!s-> in.ch_count){ av_assert0(!s->in_ch_layout); av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n"); - return -1; + ret = AVERROR(EINVAL); + goto fail; } av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout); av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout); if (s->out_ch_layout && s->out.ch_count != av_get_channel_layout_nb_channels(s->out_ch_layout)) { av_log(s, AV_LOG_ERROR, "Output channel layout %s mismatches specified channel count %d\n", l2, s->out.ch_count); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } if (s->in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s->in_ch_layout)) { av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_count); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) { av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s " "but there is not enough information to do it\n", l1, l2); - return -1; + ret = AVERROR(EINVAL); + goto fail; } av_assert0(s->used_ch_count); @@ -319,8 +324,10 @@ av_assert0(s->out.ch_count); s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt, s->int_sample_fmt, s->out.ch_count, NULL, 0); - if (!s->in_convert || !s->out_convert) - return AVERROR(ENOMEM); + if (!s->in_convert || !s->out_convert) { + ret = AVERROR(ENOMEM); + goto fail; + } s->postin= s->in; s->preout= s->out; @@ -347,12 +354,19 @@ av_assert0(s->out.ch_count); } if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0) - return ret; + goto fail; - if(s->rematrix || s->dither.method) - return swri_rematrix_init(s); + if(s->rematrix || s->dither.method) { + ret = swri_rematrix_init(s); + if (ret < 0) + goto fail; + } return 0; +fail: + swr_close(s); + return ret; + } int swri_realloc_audio(AudioData *a, int count){ -- cgit v1.2.3