Browse code

avcodec/htmlsubtitles: Fixes denial of service due to use of sscanf in inner loop for handling braces

Fixes: [Semmle Security Reports #19439]
Fixes: dos_sscanf2.mkv

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 894995c41e0795c7a44f81adc4838dedc3932e65)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

Kevin Backhouse via RT authored on 2019/02/06 21:56:01
Showing 1 changed files
... ...
@@ -22,6 +22,7 @@
22 22
 #include "libavutil/common.h"
23 23
 #include "libavutil/parseutils.h"
24 24
 #include "htmlsubtitles.h"
25
+#include <ctype.h>
25 26
 
26 27
 static int html_color_parse(void *log_ctx, const char *str)
27 28
 {
... ...
@@ -52,6 +53,25 @@ static void rstrip_spaces_buf(AVBPrint *buf)
52 52
 }
53 53
 
54 54
 /*
55
+ * Fast code for scanning text enclosed in braces. Functionally
56
+ * equivalent to this sscanf call:
57
+ *
58
+ * sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0
59
+ */
60
+static int scanbraces(const char* in) {
61
+    if (strncmp(in, "{\\an", 4) != 0) {
62
+        return 0;
63
+    }
64
+    if (!isdigit(in[4])) {
65
+        return 0;
66
+    }
67
+    if (in[5] != '}') {
68
+        return 0;
69
+    }
70
+    return 1;
71
+}
72
+
73
+/*
55 74
  * Fast code for scanning the rest of a tag. Functionally equivalent to
56 75
  * this sscanf call:
57 76
  *
... ...
@@ -110,9 +130,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
110 110
             break;
111 111
         case '{':    /* skip all {\xxx} substrings except for {\an%d}
112 112
                         and all microdvd like styles such as {Y:xxx} */
113
-            len = 0;
114
-            an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
115
-
113
+            an += scanbraces(in);
116 114
             if (!closing_brace_missing) {
117 115
                 if (   (an != 1 && in[1] == '\\')
118 116
                     || (in[1] && strchr("CcFfoPSsYy", in[1]) && in[2] == ':')) {