m->s_temp->style_start = AV_RB16(tsmb);
tsmb += 2;
m->s_temp->style_end = AV_RB16(tsmb);
+
+ if ( m->s_temp->style_end < m->s_temp->style_start
+ || (m->count_s && m->s_temp->style_start < m->s[m->count_s - 1]->style_end)) {
+ av_freep(&m->s_temp);
+ mov_text_cleanup(m);
+ return AVERROR(ENOMEM);
+ }
+
tsmb += 2;
m->s_temp->style_fontID = AV_RB16(tsmb);
tsmb += 2;
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;
}
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) {
}
}
- 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++;
}
}
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);