From: Stefano Sabatini Date: Fri, 1 Jul 2011 14:31:16 +0000 (+0200) Subject: graphparser: fix logic for updating the open_inputs/outputs in avfilter_graph_parse() X-Git-Tag: rel20110916_inqubus2.b.0~6^2~128 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=df8c675f487bc2cda2b22541cd8e5a6d8090374d;p=coroid%2Fffmpeg_saccubus.git graphparser: fix logic for updating the open_inputs/outputs in avfilter_graph_parse() Create open_inputs and open_outputs structs if they are not provided by the user, and free them before exit. In particular, fix NULL pointer dereference and crash, in case the passed open_inputs/outputs is NULL and the parsing failed. --- diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index 214729edb..edba73189 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -333,38 +333,40 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, } int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut **open_inputs, AVFilterInOut **open_outputs, + AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr, void *log_ctx) { - int index = 0, ret; + int index = 0, ret = 0; char chr = 0; AVFilterInOut *curr_inputs = NULL; + AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL; + AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL; do { AVFilterContext *filter; const char *filterchain = filters; filters += strspn(filters, WHITESPACES); - if ((ret = parse_inputs(&filters, &curr_inputs, open_outputs, log_ctx)) < 0) - goto fail; + if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0) + goto end; if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0) - goto fail; + goto end; if (filter->input_count == 1 && !curr_inputs && !index) { /* First input can be omitted if it is "[in]" */ const char *tmp = "[in]"; - if ((ret = parse_inputs(&tmp, &curr_inputs, open_outputs, log_ctx)) < 0) - goto fail; + if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0) + goto end; } - if ((ret = link_filter_inouts(filter, &curr_inputs, open_inputs, log_ctx)) < 0) - goto fail; + if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0) + goto end; - if ((ret = parse_outputs(&filters, &curr_inputs, open_inputs, open_outputs, + if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, log_ctx)) < 0) - goto fail; + goto end; filters += strspn(filters, WHITESPACES); chr = *filters++; @@ -374,7 +376,7 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, "Invalid filterchain containing an unlabelled output pad: \"%s\"\n", filterchain); ret = AVERROR(EINVAL); - goto fail; + goto end; } index++; } while (chr == ',' || chr == ';'); @@ -384,25 +386,29 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, "Unable to parse graph description substring: \"%s\"\n", filters - 1); ret = AVERROR(EINVAL); - goto fail; + goto end; } - if (open_inputs && *open_inputs && !strcmp((*open_inputs)->name, "out") && curr_inputs) { + if (open_inputs && !strcmp(open_inputs->name, "out") && curr_inputs) { /* Last output can be omitted if it is "[out]" */ const char *tmp = "[out]"; - if ((ret = parse_outputs(&tmp, &curr_inputs, open_inputs, open_outputs, + if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs, log_ctx)) < 0) - goto fail; + goto end; } - return 0; - - fail: - for (; graph->filter_count > 0; graph->filter_count--) - avfilter_free(graph->filters[graph->filter_count - 1]); - av_freep(&graph->filters); - avfilter_inout_free(open_inputs); - avfilter_inout_free(open_outputs); +end: + /* clear open_in/outputs only if not passed as parameters */ + if (open_inputs_ptr) *open_inputs_ptr = open_inputs; + else avfilter_inout_free(&open_inputs); + if (open_outputs_ptr) *open_outputs_ptr = open_outputs; + else avfilter_inout_free(&open_outputs); avfilter_inout_free(&curr_inputs); + + if (ret < 0) { + for (; graph->filter_count > 0; graph->filter_count--) + avfilter_free(graph->filters[graph->filter_count - 1]); + av_freep(&graph->filters); + } return ret; }