aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-08-23 11:12:30 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-08-23 19:57:42 +0200
commitdeb6476fd8bc3a3c2b134704ecb804269843ed89 (patch)
tree5c45257d11eb5d6609326b74e2a09200125322be
parent426c16d61a9b5056a157a1a2a057a4e4d13eef84 (diff)
downloadffmpeg-deb6476fd8bc3a3c2b134704ecb804269843ed89.tar.gz
avfilter/graphparser: Fix memleak when linking filters fails
Parsing labeled outputs involves a check for an already known match (a labeled input with the same name) to pair them together. If yes, it is attempted to create a link between the two filters; in this case the AVFilterInOuts have fulfilled their purpose and are freed. Yet if creating the link fails, these AVFilterInOuts have up until now not been freed, although they had already been removed from their respective lists (which means that they are not freed automatically). In other words: They leak. This commit fixes this. This fixes ticket #7084. Said ticket contains an example program to reproduce a leak. It can also be reproduced with ffmpeg alone, e.g. with the complex filters "[0]null[1],[2]anull[0]" or with "[0]abitscope[0]". All of these three examples involve media type mismatches which make it impossible to create the links. The bug could also be triggered by other means, e.g. failure to allocate the necessary AVFilterLink. Reviewed-by: Nicolas George <george@nsup.org> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
-rw-r--r--libavfilter/graphparser.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index a52916a146..1385c3ae71 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -372,15 +372,14 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
match = extract_inout(name, open_inputs);
if (match) {
- if ((ret = link_filter(input->filter_ctx, input->pad_idx,
- match->filter_ctx, match->pad_idx, log_ctx)) < 0) {
- av_free(name);
- return ret;
- }
+ ret = link_filter(input->filter_ctx, input->pad_idx,
+ match->filter_ctx, match->pad_idx, log_ctx);
av_freep(&match->name);
av_freep(&name);
av_freep(&match);
av_freep(&input);
+ if (ret < 0)
+ return ret;
} else {
/* Not in the list, so add the first input as an open_output */
input->name = name;