diff mbox series

[FFmpeg-devel,v5,1/4] avutil/{avstring, bprint}: add XML escaping from ffprobe to avutil

Message ID 20210222131914.21335-2-jeebjp@gmail.com
State Superseded
Headers show
Series Initial implementation of TTML encoding/muxing
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Jan Ekström Feb. 22, 2021, 1:19 p.m. UTC
From: Stefano Sabatini <stefasab@gmail.com>

Base escaping only escapes values required for base character data
according to part 2.4 of XML, and if additional flags are added
single and double quotes can additionally be escaped in order
to handle single and double quoted attributes.
---
 libavutil/avstring.h | 14 ++++++++++++++
 libavutil/bprint.c   | 29 +++++++++++++++++++++++++++++
 libavutil/version.h  |  2 +-
 tools/ffescape.c     |  7 +++++--
 4 files changed, 49 insertions(+), 3 deletions(-)

Comments

Nicolas George Feb. 26, 2021, 9:43 a.m. UTC | #1
Jan Ekström (12021-02-22):
> From: Stefano Sabatini <stefasab@gmail.com>
> 
> Base escaping only escapes values required for base character data
> according to part 2.4 of XML, and if additional flags are added
> single and double quotes can additionally be escaped in order
> to handle single and double quoted attributes.
> ---
>  libavutil/avstring.h | 14 ++++++++++++++
>  libavutil/bprint.c   | 29 +++++++++++++++++++++++++++++
>  libavutil/version.h  |  2 +-
>  tools/ffescape.c     |  7 +++++--
>  4 files changed, 49 insertions(+), 3 deletions(-)

I am happy with this version. Thank you very much.

Regards,
Michael Niedermayer Feb. 26, 2021, 5:54 p.m. UTC | #2
On Mon, Feb 22, 2021 at 03:19:11PM +0200, Jan Ekström wrote:
> From: Stefano Sabatini <stefasab@gmail.com>
> 
> Base escaping only escapes values required for base character data
> according to part 2.4 of XML, and if additional flags are added
> single and double quotes can additionally be escaped in order
> to handle single and double quoted attributes.
> ---
>  libavutil/avstring.h | 14 ++++++++++++++
>  libavutil/bprint.c   | 29 +++++++++++++++++++++++++++++
>  libavutil/version.h  |  2 +-
>  tools/ffescape.c     |  7 +++++--
>  4 files changed, 49 insertions(+), 3 deletions(-)

breaks: tools/ffescape.o

CC	tools/ffescape.o
tools/ffescape.c: In function ‘main’:
tools/ffescape.c:83:59: error: expected ‘)’ before ‘escape_flags’
             else if (!strcmp(optarg, "xml_single_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES);
                                                           ^~~~~~~~~~~~
tools/ffescape.c:84:59: error: expected ‘)’ before ‘escape_flags’
             else if (!strcmp(optarg, "xml_double_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
                                                           ^~~~~~~~~~~~
ffbuild/common.mak:67: recipe for target 'tools/ffescape.o' failed
make: *** [tools/ffescape.o] Error 1


[...]
Jan Ekström Feb. 26, 2021, 7 p.m. UTC | #3
On Fri, Feb 26, 2021 at 7:54 PM Michael Niedermayer
<michael@niedermayer.cc> wrote:
>
> On Mon, Feb 22, 2021 at 03:19:11PM +0200, Jan Ekström wrote:
> > From: Stefano Sabatini <stefasab@gmail.com>
> >
> > Base escaping only escapes values required for base character data
> > according to part 2.4 of XML, and if additional flags are added
> > single and double quotes can additionally be escaped in order
> > to handle single and double quoted attributes.
> > ---
> >  libavutil/avstring.h | 14 ++++++++++++++
> >  libavutil/bprint.c   | 29 +++++++++++++++++++++++++++++
> >  libavutil/version.h  |  2 +-
> >  tools/ffescape.c     |  7 +++++--
> >  4 files changed, 49 insertions(+), 3 deletions(-)
>
> breaks: tools/ffescape.o
>
> CC      tools/ffescape.o
> tools/ffescape.c: In function ‘main’:
> tools/ffescape.c:83:59: error: expected ‘)’ before ‘escape_flags’
>              else if (!strcmp(optarg, "xml_single_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES);
>                                                            ^~~~~~~~~~~~
> tools/ffescape.c:84:59: error: expected ‘)’ before ‘escape_flags’
>              else if (!strcmp(optarg, "xml_double_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
>                                                            ^~~~~~~~~~~~
> ffbuild/common.mak:67: recipe for target 'tools/ffescape.o' failed
> make: *** [tools/ffescape.o] Error 1

OK, sorry. That is a clear mistake yet I somehow thought that was
built by default and thus it was OK :/

Will fix.

Jan
Jan Ekström Feb. 26, 2021, 7:14 p.m. UTC | #4
On Fri, Feb 26, 2021 at 9:00 PM Jan Ekström <jeebjp@gmail.com> wrote:
>
> On Fri, Feb 26, 2021 at 7:54 PM Michael Niedermayer
> <michael@niedermayer.cc> wrote:
> >
> > On Mon, Feb 22, 2021 at 03:19:11PM +0200, Jan Ekström wrote:
> > > From: Stefano Sabatini <stefasab@gmail.com>
> > >
> > > Base escaping only escapes values required for base character data
> > > according to part 2.4 of XML, and if additional flags are added
> > > single and double quotes can additionally be escaped in order
> > > to handle single and double quoted attributes.
> > > ---
> > >  libavutil/avstring.h | 14 ++++++++++++++
> > >  libavutil/bprint.c   | 29 +++++++++++++++++++++++++++++
> > >  libavutil/version.h  |  2 +-
> > >  tools/ffescape.c     |  7 +++++--
> > >  4 files changed, 49 insertions(+), 3 deletions(-)
> >
> > breaks: tools/ffescape.o
> >
> > CC      tools/ffescape.o
> > tools/ffescape.c: In function ‘main’:
> > tools/ffescape.c:83:59: error: expected ‘)’ before ‘escape_flags’
> >              else if (!strcmp(optarg, "xml_single_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES);
> >                                                            ^~~~~~~~~~~~
> > tools/ffescape.c:84:59: error: expected ‘)’ before ‘escape_flags’
> >              else if (!strcmp(optarg, "xml_double_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
> >                                                            ^~~~~~~~~~~~
> > ffbuild/common.mak:67: recipe for target 'tools/ffescape.o' failed
> > make: *** [tools/ffescape.o] Error 1
>
> OK, sorry. That is a clear mistake yet I somehow thought that was
> built by default and thus it was OK :/
>
> Will fix.
>

Is now fixed as:

diff --git a/tools/ffescape.c b/tools/ffescape.c
index 0530d28c6d..1ed8daa801 100644
--- a/tools/ffescape.c
+++ b/tools/ffescape.c
@@ -78,8 +78,10 @@ int main(int argc, char **argv)
             infilename = optarg;
             break;
         case 'f':
-            if      (!strcmp(optarg, "whitespace")) escape_flags |=
AV_ESCAPE_FLAG_WHITESPACE;
-            else if (!strcmp(optarg, "strict"))     escape_flags |=
AV_ESCAPE_FLAG_STRICT;
+            if      (!strcmp(optarg, "whitespace"))
escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
+            else if (!strcmp(optarg, "strict"))
escape_flags |= AV_ESCAPE_FLAG_STRICT;
+            else if (!strcmp(optarg, "xml_single_quotes"))
escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES;
+            else if (!strcmp(optarg, "xml_double_quotes"))
escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES;
             else {
                 av_log(NULL, AV_LOG_ERROR,
                        "Invalid value '%s' for option -f, "
@@ -104,6 +106,7 @@ int main(int argc, char **argv)
             if      (!strcmp(optarg, "auto"))      escape_mode =
AV_ESCAPE_MODE_AUTO;
             else if (!strcmp(optarg, "backslash")) escape_mode =
AV_ESCAPE_MODE_BACKSLASH;
             else if (!strcmp(optarg, "quote"))     escape_mode =
AV_ESCAPE_MODE_QUOTE;
+            else if (!strcmp(optarg, "xml"))       escape_mode =
AV_ESCAPE_MODE_XML;
             else {
                 av_log(NULL, AV_LOG_ERROR,
                        "Invalid value '%s' for option -m, "
diff mbox series

Patch

diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index ee225585b3..fae446c302 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -324,6 +324,7 @@  enum AVEscapeMode {
     AV_ESCAPE_MODE_AUTO,      ///< Use auto-selected escaping mode.
     AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping.
     AV_ESCAPE_MODE_QUOTE,     ///< Use single-quote escaping.
+    AV_ESCAPE_MODE_XML,       ///< Use XML non-markup character data escaping.
 };
 
 /**
@@ -343,6 +344,19 @@  enum AVEscapeMode {
  */
 #define AV_ESCAPE_FLAG_STRICT (1 << 1)
 
+/**
+ * Within AV_ESCAPE_MODE_XML, additionally escape single quotes for single
+ * quoted attributes.
+ */
+#define AV_ESCAPE_FLAG_XML_SINGLE_QUOTES (1 << 2)
+
+/**
+ * Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double
+ * quoted attributes.
+ */
+#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES (1 << 3)
+
+
 /**
  * Escape string in src, and put the escaped string in an allocated
  * string in *dst, which must be freed with av_free().
diff --git a/libavutil/bprint.c b/libavutil/bprint.c
index 2f059c5ba6..e12fb263fe 100644
--- a/libavutil/bprint.c
+++ b/libavutil/bprint.c
@@ -283,6 +283,35 @@  void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_cha
         av_bprint_chars(dstbuf, '\'', 1);
         break;
 
+    case AV_ESCAPE_MODE_XML:
+        /* escape XML non-markup character data as per 2.4 by default: */
+        /*  [^<&]* - ([^<&]* ']]>' [^<&]*) */
+
+        /* additionally, given one of the AV_ESCAPE_FLAG_XML_* flags, */
+        /* escape those specific characters as required. */
+        for (; *src; src++) {
+            switch (*src) {
+            case '&' : av_bprintf(dstbuf, "%s", "&amp;");  break;
+            case '<' : av_bprintf(dstbuf, "%s", "&lt;");   break;
+            case '>' : av_bprintf(dstbuf, "%s", "&gt;");   break;
+            case '\'':
+                if (!(flags & AV_ESCAPE_FLAG_XML_SINGLE_QUOTES))
+                    goto XML_DEFAULT_HANDLING;
+
+                av_bprintf(dstbuf, "%s", "&apos;");
+                break;
+            case '"' :
+                if (!(flags & AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES))
+                    goto XML_DEFAULT_HANDLING;
+
+                av_bprintf(dstbuf, "%s", "&quot;");
+                break;
+XML_DEFAULT_HANDLING:
+            default: av_bprint_chars(dstbuf, *src, 1);
+            }
+        }
+        break;
+
     /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */
     default:
         /* \-escape characters */
diff --git a/libavutil/version.h b/libavutil/version.h
index b7c5892a37..356c54d633 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@ 
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  66
+#define LIBAVUTIL_VERSION_MINOR  67
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
diff --git a/tools/ffescape.c b/tools/ffescape.c
index 0530d28c6d..3647ae5d60 100644
--- a/tools/ffescape.c
+++ b/tools/ffescape.c
@@ -78,8 +78,10 @@  int main(int argc, char **argv)
             infilename = optarg;
             break;
         case 'f':
-            if      (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
-            else if (!strcmp(optarg, "strict"))     escape_flags |= AV_ESCAPE_FLAG_STRICT;
+            if      (!strcmp(optarg, "whitespace"))       escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
+            else if (!strcmp(optarg, "strict"))           escape_flags |= AV_ESCAPE_FLAG_STRICT;
+            else if (!strcmp(optarg, "xml_single_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES);
+            else if (!strcmp(optarg, "xml_double_quotes") escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
             else {
                 av_log(NULL, AV_LOG_ERROR,
                        "Invalid value '%s' for option -f, "
@@ -104,6 +106,7 @@  int main(int argc, char **argv)
             if      (!strcmp(optarg, "auto"))      escape_mode = AV_ESCAPE_MODE_AUTO;
             else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH;
             else if (!strcmp(optarg, "quote"))     escape_mode = AV_ESCAPE_MODE_QUOTE;
+            else if (!strcmp(optarg, "xml"))       escape_mode = AV_ESCAPE_MODE_XML;
             else {
                 av_log(NULL, AV_LOG_ERROR,
                        "Invalid value '%s' for option -m, "