From bbc5adfb9428e1cbfcc323db700578059f8fa253 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 23 Jul 2014 08:36:24 +0200 Subject: [PATCH] avutil/opt: Fix parsing regression with constants starting with numbers Fixes parsing "3dnow" Found-by: jamrial Signed-off-by: Michael Niedermayer --- libavutil/opt.c | 63 ++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 693e846cdd..c1ca4a817b 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -206,44 +206,47 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con } { - const AVOption *o_named; + const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0); int res; int ci = 0; double const_values[64]; const char * const_names[64]; - - if (o->unit) { - for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) { - if (o_named->type == AV_OPT_TYPE_CONST && - o_named->unit && - !strcmp(o_named->unit, o->unit)) { - if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) { - av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit); - return AVERROR_PATCHWELCOME; + if (o_named && o_named->type == AV_OPT_TYPE_CONST) + d = DEFAULT_NUMVAL(o_named); + else { + if (o->unit) { + for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) { + if (o_named->type == AV_OPT_TYPE_CONST && + o_named->unit && + !strcmp(o_named->unit, o->unit)) { + if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) { + av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit); + return AVERROR_PATCHWELCOME; + } + const_names [ci ] = o_named->name; + const_values[ci++] = DEFAULT_NUMVAL(o_named); } - const_names [ci ] = o_named->name; - const_values[ci++] = DEFAULT_NUMVAL(o_named); } } - } - const_names [ci ] = "default"; - const_values[ci++] = DEFAULT_NUMVAL(o); - const_names [ci ] = "max"; - const_values[ci++] = o->max; - const_names [ci ] = "min"; - const_values[ci++] = o->min; - const_names [ci ] = "none"; - const_values[ci++] = 0; - const_names [ci ] = "all"; - const_values[ci++] = ~0; - const_names [ci] = NULL; - const_values[ci] = 0; + const_names [ci ] = "default"; + const_values[ci++] = DEFAULT_NUMVAL(o); + const_names [ci ] = "max"; + const_values[ci++] = o->max; + const_names [ci ] = "min"; + const_values[ci++] = o->min; + const_names [ci ] = "none"; + const_values[ci++] = 0; + const_names [ci ] = "all"; + const_values[ci++] = ~0; + const_names [ci] = NULL; + const_values[ci] = 0; - res = av_expr_parse_and_eval(&d, i ? buf : val, const_names, - const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); - if (res < 0) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); - return res; + res = av_expr_parse_and_eval(&d, i ? buf : val, const_names, + const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); + if (res < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); + return res; + } } } if (o->type == AV_OPT_TYPE_FLAGS) {