summaryrefslogtreecommitdiff
path: root/libavcodec/movtextdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/movtextdec.c')
-rw-r--r--libavcodec/movtextdec.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
index bd19577724..89ac791602 100644
--- a/libavcodec/movtextdec.c
+++ b/libavcodec/movtextdec.c
@@ -326,9 +326,24 @@ static const Box box_types[] = {
const static size_t box_count = FF_ARRAY_ELEMS(box_types);
+// Return byte length of the UTF-8 sequence starting at text[0]. 0 on error.
+static int get_utf8_length_at(const char *text, const char *text_end)
+{
+ const char *start = text;
+ int err = 0;
+ uint32_t c;
+ GET_UTF8(c, text < text_end ? (uint8_t)*text++ : (err = 1, 0), goto error;);
+ if (err)
+ goto error;
+ return text - start;
+error:
+ return 0;
+}
+
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end,
- MovTextContext *m)
+ AVCodecContext *avctx)
{
+ MovTextContext *m = avctx->priv_data;
int i = 0;
int j = 0;
int text_pos = 0;
@@ -342,6 +357,8 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end,
}
while (text < text_end) {
+ int len;
+
if (m->box_flags & STYL_BOX) {
for (i = 0; i < m->style_entries; i++) {
if (m->s[i]->style_flag && text_pos == m->s[i]->style_end) {
@@ -388,17 +405,24 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end,
}
}
- switch (*text) {
- case '\r':
- break;
- case '\n':
- av_bprintf(buf, "\\N");
- break;
- default:
- av_bprint_chars(buf, *text, 1);
- break;
+ len = get_utf8_length_at(text, text_end);
+ if (len < 1) {
+ av_log(avctx, AV_LOG_ERROR, "invalid UTF-8 byte in subtitle\n");
+ len = 1;
+ }
+ for (i = 0; i < len; i++) {
+ switch (*text) {
+ case '\r':
+ break;
+ case '\n':
+ av_bprintf(buf, "\\N");
+ break;
+ default:
+ av_bprint_chars(buf, *text, 1);
+ break;
+ }
+ text++;
}
- text++;
text_pos++;
}
@@ -507,10 +531,10 @@ static int mov_text_decode_frame(AVCodecContext *avctx,
}
m->tracksize = m->tracksize + tsmb_size;
}
- text_to_ass(&buf, ptr, end, m);
+ text_to_ass(&buf, ptr, end, avctx);
mov_text_cleanup(m);
} else
- text_to_ass(&buf, ptr, end, m);
+ text_to_ass(&buf, ptr, end, avctx);
ret = ff_ass_add_rect(sub, buf.str, m->readorder++, 0, NULL, NULL);
av_bprint_finalize(&buf, NULL);