aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Backhouse via RT <security-reports@semmle.com>2019-02-06 12:56:01 +0000
committerMichael Niedermayer <michael@niedermayer.cc>2019-03-14 00:24:44 +0100
commitf7f3937494f6734d27fc3d0081c9c7a9a19614a8 (patch)
tree9756e5cfa3fd598363bcebbfd51ce835444184b5
parentcc5361ed18ab0f69cfbead7afc88fb81ed4b36ae (diff)
downloadffmpeg-f7f3937494f6734d27fc3d0081c9c7a9a19614a8.tar.gz
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>
-rw-r--r--libavcodec/htmlsubtitles.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c
index c0cfccfb16..d9221ba16b 100644
--- a/libavcodec/htmlsubtitles.c
+++ b/libavcodec/htmlsubtitles.c
@@ -24,6 +24,7 @@
#include "libavutil/common.h"
#include "libavutil/parseutils.h"
#include "htmlsubtitles.h"
+#include <ctype.h>
static int html_color_parse(void *log_ctx, const char *str)
{
@@ -44,14 +45,32 @@ static void rstrip_spaces_buf(AVBPrint *buf)
buf->str[--buf->len] = 0;
}
+/*
+ * Fast code for scanning text enclosed in braces. Functionally
+ * equivalent to this sscanf call:
+ *
+ * sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0
+ */
+static int scanbraces(const char* in) {
+ if (strncmp(in, "{\\an", 4) != 0) {
+ return 0;
+ }
+ if (!isdigit(in[4])) {
+ return 0;
+ }
+ if (in[5] != '}') {
+ return 0;
+ }
+ return 1;
+}
+
/* skip all {\xxx} substrings except for {\an%d}
and all microdvd like styles such as {Y:xxx} */
static void handle_open_brace(AVBPrint *dst, const char **inp, int *an, int *closing_brace_missing)
{
- int len = 0;
const char *in = *inp;
- *an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
+ *an += scanbraces(in);
if (!*closing_brace_missing) {
if ( (*an != 1 && in[1] == '\\')