[FFmpeg-devel] [PATCH 25/38] avfilter/avfilter: Honour the short options documentation
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Mon Sep 13 15:15:39 EEST 2021
Nicolas George:
> Andreas Rheinhardt (12021-09-12):
>> The documentation for filter arguments states that short options must
>> precede long options (i.e. those of the form key=value). Yet if
>> process_options() encounters arguments not abiding by this, it simply
>> treats short options after a long option as if it were parsing short
>> options for the first time. In particular, it overwrites options already
>> set earlier, possibly via other short options. This is not how it is
>> intended (as a comment in the code indicates).
>>
>> This commit modifies the code to reject further shorthand options
>> after a long option has been encountered. After all, avfilter_init_str()
>> errors out upon unrecognized options, so it is intended to be picky.
>>
>> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
>> ---
>> The while loop that is removed below is actually just an elaborate
>> "o = NULL", which av_opt_next() interprets as "start the iteration".
>>
>> libavfilter/avfilter.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
>> index cc499fd5ed..165ab1f44a 100644
>> --- a/libavfilter/avfilter.c
>> +++ b/libavfilter/avfilter.c
>> @@ -814,6 +814,7 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,
>> const AVOption *o = NULL;
>> int ret;
>> char *av_uninit(parsed_key), *av_uninit(value);
>
>> + const AVClass *priv = ctx->filter->priv_class;
>
> I do not understand why you make this a pointer rather than an int,
> since it is only used as a boolean. "int shorthand_allowed" would be
> clearer IMHO.
>
This is in preparation for the next patch: In this case,
process_options() will be called for filters without AVClass. It is not
documented to be save to call the av_opt_* functions with a
non-AVOpt-enabled structure and this check automatically ensures that it
won't be called in this case. (av_opt_next() currently does not crash,
but returns NULL.)
- Andreas
>> const char *key;
>> int offset= -1;
>>
>> @@ -824,8 +825,7 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,
>> const char *shorthand = NULL;
>> int flags = AV_DICT_DONT_STRDUP_VAL;
>>
>> - o = av_opt_next(ctx->priv, o);
>> - if (o) {
>> + if (priv && (o = av_opt_next(ctx->priv, o))) {
>> if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
>> continue;
>> offset = o->offset;
>> @@ -848,7 +848,7 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,
>> if (parsed_key) {
>> key = parsed_key;
>> flags |= AV_DICT_DONT_STRDUP_KEY;
>> - while ((o = av_opt_next(ctx->priv, o))); /* discard all remaining shorthand */
>> + priv = NULL; /* reject all remaining shorthand */
>> } else {
>> key = shorthand;
>> }
>
> Regards,
>
More information about the ffmpeg-devel
mailing list