]> git.sesse.net Git - ffmpeg/commitdiff
avutil/{avstring,bprint}: add XML escaping from ffprobe to avutil
authorStefano Sabatini <stefasab@gmail.com>
Mon, 16 Nov 2020 07:38:39 +0000 (09:38 +0200)
committerJan Ekström <jeebjp@gmail.com>
Fri, 5 Mar 2021 17:45:00 +0000 (19:45 +0200)
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.

Co-authored-by: Jan Ekström <jan.ekstrom@24i.com>
Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
libavutil/avstring.h
libavutil/bprint.c
libavutil/version.h
tools/ffescape.c

index ee225585b3dcd6c6e2f97124d9a2b026667e606a..fae446c3027449595a56d44375b5b9a6671c1005 100644 (file)
@@ -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().
index 2f059c5ba6bfd66e6d9fd98d02394fa226b92776..e12fb263fe791090f013d50b9b9f53a5ca59d054 100644 (file)
@@ -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 */
index b7c5892a37ed65c44becc12a10a35dc713197a38..356c54d6337bbfa7894c23a38ccc581909ed763d 100644 (file)
@@ -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, \
index 0530d28c6d672980471a55be1e3c78a0b88b5b87..1ed8daa801042b0e5d7fe85115e4b9df6c7029f3 100644 (file)
@@ -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, "