diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2013-04-07 09:51:23 +0200 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2013-04-24 19:41:27 +0200 |
commit | 70feca926b93f339cb58c340550e9a2367263bf7 (patch) | |
tree | e158e7fe9e3a231014620bea453dcdc2a18f66d8 /libavcodec | |
parent | 29ebb7ba8d7e25b8a522393f1866a27e50869ba9 (diff) | |
download | ffmpeg-70feca926b93f339cb58c340550e9a2367263bf7.tar.gz |
lavc: check decoded subtitles encoding.
Address trac ticket #2431.
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/utils.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1733d0f1a3..1f4793c1a3 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2206,11 +2206,30 @@ end: #endif } +static int utf8_check(const uint8_t *str) +{ + const uint8_t *byte; + uint32_t codepoint, min; + + while (*str) { + byte = str; + GET_UTF8(codepoint, *(byte++), return 0;); + min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : + 1 << (5 * (byte - str) - 4); + if (codepoint < min || codepoint >= 0x110000 || + codepoint == 0xFFFE /* BOM */ || + codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) + return 0; + str = byte; + } + return 1; +} + int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) { - int ret = 0; + int i, ret = 0; if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); @@ -2247,6 +2266,16 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, avctx->pkt_timebase, ms); } + for (i = 0; i < sub->num_rects; i++) { + if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid UTF-8 in decoded subtitles text; " + "maybe missing -sub_charenc option\n"); + avsubtitle_free(sub); + return AVERROR_INVALIDDATA; + } + } + if (tmp.data != pkt_recoded.data) { // did we recode? /* prevent from destroying side data from original packet */ pkt_recoded.side_data = NULL; |