[FFmpeg-devel] lavu/opt: add escaping to av_opt_serialize

Stefano Sabatini stefasab at gmail.com
Thu Nov 27 15:05:06 CET 2014


On date Tuesday 2014-11-25 20:38:59 +0100, Lukasz Marek encoded:
> Patch attached.

> From 2a9de161df4e1d0083264dde94ec5b8af59cec35 Mon Sep 17 00:00:00 2001
> From: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> Date: Tue, 25 Nov 2014 20:25:10 +0100
> Subject: [PATCH] lavu/opt: add escaping to av_opt_serialize
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> ---
>  libavutil/opt.c    | 12 +++++++++++-
>  libavutil/opt.h    |  1 +
>  tests/ref/fate/opt |  7 +++++--
>  3 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/libavutil/opt.c b/libavutil/opt.c
> index 0546a37..5b9cc35 100644
> --- a/libavutil/opt.c
> +++ b/libavutil/opt.c
> @@ -1843,6 +1843,11 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
>      uint8_t *buf;
>      AVBPrint bprint;
>      int ret, cnt = 0;
> +    const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
> +
> +    if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
> +        pairs_sep == '\\' || key_val_sep == '\\')
> +        return AVERROR(EINVAL);

maybe send a log here

>      if (!obj || !buffer)
>          return AVERROR(EINVAL);
> @@ -1866,7 +1871,9 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
>          if (buf) {
>              if (cnt++)
>                  av_bprint_append_data(&bprint, &pairs_sep, 1);
> -            av_bprintf(&bprint, "%s%c%s", o->name, key_val_sep, buf);
> +            av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
> +            av_bprint_append_data(&bprint, &key_val_sep, 1);
> +            av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
>              av_freep(&buf);
>          }
>      }
> @@ -1900,6 +1907,7 @@ typedef struct TestContext
>      int64_t num64;
>      float flt;
>      double dbl;
> +    char *escape;
>  } TestContext;
>  
>  #define OFFSET(x) offsetof(TestContext, x)
> @@ -1913,6 +1921,7 @@ static const AVOption test_options[]= {
>  {"toggle",   "set toggle",     OFFSET(toggle),   AV_OPT_TYPE_INT,      {.i64 = 1},       0,        1                   },
>  {"rational", "set rational",   OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 1},       0,        10                  },
>  {"string",   "set string",     OFFSET(string),   AV_OPT_TYPE_STRING,   {.str = "default"}, CHAR_MIN, CHAR_MAX          },
> +{"escape",   "set escape str", OFFSET(escape),   AV_OPT_TYPE_STRING,   {.str = "\\=,"}, CHAR_MIN, CHAR_MAX             },
>  {"flags",    "set flags",      OFFSET(flags),    AV_OPT_TYPE_FLAGS,    {.i64 = 1},       0,        INT_MAX, 0, "flags" },
>  {"cool",     "set cool flag ", 0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_COOL}, INT_MIN,  INT_MAX, 0, "flags" },
>  {"lame",     "set lame flag ", 0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_LAME}, INT_MIN,  INT_MAX, 0, "flags" },
> @@ -1957,6 +1966,7 @@ int main(void)
>          printf("num=%d\n", test_ctx.num);
>          printf("toggle=%d\n", test_ctx.toggle);
>          printf("string=%s\n", test_ctx.string);
> +        printf("escape=%s\n", test_ctx.escape);
>          printf("flags=%d\n", test_ctx.flags);
>          printf("rational=%d/%d\n", test_ctx.rational.num, test_ctx.rational.den);
>          printf("video_rate=%d/%d\n", test_ctx.video_rate.num, test_ctx.video_rate.den);
> diff --git a/libavutil/opt.h b/libavutil/opt.h
> index 7338e78..777fc3b 100644
> --- a/libavutil/opt.h
> +++ b/libavutil/opt.h
> @@ -887,6 +887,7 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla
>   * @param[in]  key_val_sep   character used to separate key from value
>   * @param[in]  pairs_sep     character used to separate two pairs from each other
>   * @return                   >= 0 on success, negative on error
> + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same.
>   */

You could mention escaping in the docs, for example:

A key/value or pairs separator occurring in the serialized value or
name string are escaped through the av_escape() function.

>  int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
>                       const char key_val_sep, const char pairs_sep);
> diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt
> index 16f3387..084a222 100644
> --- a/tests/ref/fate/opt
> +++ b/tests/ref/fate/opt
> @@ -2,6 +2,7 @@ Testing default values
>  num=0
>  toggle=1
>  string=default
> +escape=\=,
>  flags=1
>  rational=1/1
>  video_rate=25/1
> @@ -22,6 +23,7 @@ name:       num default:1 error:
>  name:    toggle default:0 error:
>  name:  rational default:0 error:
>  name:    string default:0 error:
> +name:    escape default:0 error:
>  name:     flags default:0 error:
>  name:      cool default:1 error:Option not found
>  name:      lame default:1 error:Option not found
> @@ -43,6 +45,7 @@ name:       num default:1 error:
>  name:    toggle default:1 error:
>  name:  rational default:1 error:
>  name:    string default:1 error:
> +name:    escape default:1 error:
>  name:     flags default:1 error:
>  name:      cool default:1 error:Option not found
>  name:      lame default:1 error:Option not found
> @@ -62,8 +65,8 @@ name:       flt default:1 error:
>  name:       dbl default:1 error:
>  
>  Test av_opt_serialize()
> -num=0,toggle=1,rational=1/1,string=default,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
> -num=0,toggle=1,rational=1/1,string=default,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
> +num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
> +num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
>  
>  Testing av_set_options_string()
>  OK    ''

LGTM otherwise, thanks.
-- 
FFmpeg = Funny and Forgiving Meaningless Ponderous Empowered Gadget


More information about the ffmpeg-devel mailing list