Skip to content
Snippets Groups Projects
Commit 273f2755 authored by Kevin Backhouse via RT's avatar Kevin Backhouse via RT Committed by Michael Niedermayer
Browse files

avcodec/htmlsubtitles: Fixes denial of service due to use of sscanf in inner...

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: default avatarMichael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 894995c4)
Signed-off-by: default avatarMichael Niedermayer <michael@niedermayer.cc>
parent 23ccf3ca
No related branches found
No related tags found
No related merge requests found
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "libavutil/common.h" #include "libavutil/common.h"
#include "libavutil/parseutils.h" #include "libavutil/parseutils.h"
#include "htmlsubtitles.h" #include "htmlsubtitles.h"
#include <ctype.h>
static int html_color_parse(void *log_ctx, const char *str) static int html_color_parse(void *log_ctx, const char *str)
{ {
...@@ -51,6 +52,25 @@ static void rstrip_spaces_buf(AVBPrint *buf) ...@@ -51,6 +52,25 @@ static void rstrip_spaces_buf(AVBPrint *buf)
buf->str[--buf->len] = 0; 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;
}
/* /*
* Fast code for scanning the rest of a tag. Functionally equivalent to * Fast code for scanning the rest of a tag. Functionally equivalent to
* this sscanf call: * this sscanf call:
...@@ -110,9 +130,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) ...@@ -110,9 +130,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
break; break;
case '{': /* skip all {\xxx} substrings except for {\an%d} case '{': /* skip all {\xxx} substrings except for {\an%d}
and all microdvd like styles such as {Y:xxx} */ and all microdvd like styles such as {Y:xxx} */
len = 0; an += scanbraces(in);
an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
if (!closing_brace_missing) { if (!closing_brace_missing) {
if ( (an != 1 && in[1] == '\\') if ( (an != 1 && in[1] == '\\')
|| (in[1] && strchr("CcFfoPSsYy", in[1]) && in[2] == ':')) { || (in[1] && strchr("CcFfoPSsYy", in[1]) && in[2] == ':')) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment