[FFmpeg-devel] [PATCH] avfilter/formats: fix leak of channel_layouts on error

Ganesh Ajjanagadde gajjanag at mit.edu
Sat Jan 2 21:27:18 CET 2016


On Sat, Jan 2, 2016 at 12:06 PM, Paul B Mahol <onemda at gmail.com> wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  libavfilter/formats.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/libavfilter/formats.c b/libavfilter/formats.c
> index a2b19e7..37d202f 100644
> --- a/libavfilter/formats.c
> +++ b/libavfilter/formats.c
> @@ -507,7 +507,16 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
>      FORMATS_CHANGEREF(oldref, newref);
>  }
>
> -#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list) \
> +static void free_channel_layouts(AVFilterChannelLayouts *layouts)
> +{
> +    av_freep(&layouts->channel_layouts);
> +}
> +
> +static void do_nothing(AVFilterFormats *formats)
> +{
> +}
> +
> +#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list, free_chl) \
>      int count = 0, i;                                               \
>                                                                      \
>      if (!fmts)                                                      \
> @@ -517,6 +526,7 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
>          if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
>              int ret = ref_fn(fmts, &ctx->inputs[i]->out_fmts);      \
>              if (ret < 0) {                                          \
> +                free_chl(fmts);                                     \
>                  unref_fn(&fmts);                                    \
>                  return ret;                                         \
>              }                                                       \
> @@ -527,6 +537,7 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
>          if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
>              int ret = ref_fn(fmts, &ctx->outputs[i]->in_fmts);      \
>              if (ret < 0) {                                          \
> +                free_chl(fmts);                                     \
>                  unref_fn(&fmts);                                    \
>                  return ret;                                         \
>              }                                                       \
> @@ -537,6 +548,7 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
>      if (!count) {                                                   \
>          av_freep(&fmts->list);                                      \
>          av_freep(&fmts->refs);                                      \
> +        free_chl(fmts);                                             \
>          av_freep(&fmts);                                            \
>      }                                                               \
>                                                                      \
> @@ -546,14 +558,15 @@ int ff_set_common_channel_layouts(AVFilterContext *ctx,
>                                    AVFilterChannelLayouts *layouts)
>  {
>      SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
> -                       ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts);
> +                       ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts,
> +                       free_channel_layouts);
>  }
>
>  int ff_set_common_samplerates(AVFilterContext *ctx,
>                                AVFilterFormats *samplerates)
>  {
>      SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
> -                       ff_formats_ref, ff_formats_unref, formats);
> +                       ff_formats_ref, ff_formats_unref, formats, do_nothing);
>  }
>
>  /**
> @@ -564,7 +577,7 @@ int ff_set_common_samplerates(AVFilterContext *ctx,
>  int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
>  {
>      SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
> -                       ff_formats_ref, ff_formats_unref, formats);
> +                       ff_formats_ref, ff_formats_unref, formats, do_nothing);
>  }

Thanks a lot for addressing this. But a client may not necessarily
attempt initialization of the channel layouts first, so instead of
do_nothing calls, shouldn't there be an equivalent for
AVFilterFormats*?

Of course, the commit message will need rewording.


More information about the ffmpeg-devel mailing list