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.lu...@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.lu...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel