X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Ftedcaptionsdec.c;h=94e8432c532670779fe0078de058cb20ebdb7fdb;hb=bc70684e74a185d7b80c8b80bdedda659cb581b8;hp=cd6ab0c24b7d2efe74d17f3ffa8f2dfb14b175a9;hpb=4dc1f06f0c84ebbd8b26cd77679450903244a3e8;p=ffmpeg diff --git a/libavformat/tedcaptionsdec.c b/libavformat/tedcaptionsdec.c index cd6ab0c24b7..94e8432c532 100644 --- a/libavformat/tedcaptionsdec.c +++ b/libavformat/tedcaptionsdec.c @@ -94,25 +94,20 @@ static int parse_string(AVIOContext *pb, int *cur_byte, AVBPrint *bp, int full) { int ret; - av_bprint_init(bp, 0, full ? AV_BPRINT_SIZE_UNLIMITED : AV_BPRINT_SIZE_AUTOMATIC); ret = expect_byte(pb, cur_byte, '"'); if (ret < 0) - goto fail; + return ret; while (*cur_byte > 0 && *cur_byte != '"') { if (*cur_byte == '\\') { next_byte(pb, cur_byte); - if (*cur_byte < 0) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (*cur_byte < 0) + return AVERROR_INVALIDDATA; if ((*cur_byte | 32) == 'u') { unsigned chr = 0, i; for (i = 0; i < 4; i++) { next_byte(pb, cur_byte); - if (!HEX_DIGIT_TEST(*cur_byte)) { - ret = ERR_CODE(*cur_byte); - goto fail; - } + if (!HEX_DIGIT_TEST(*cur_byte)) + return ERR_CODE(*cur_byte); chr = chr * 16 + HEX_DIGIT_VAL(*cur_byte); } av_bprint_utf8(bp, chr); @@ -126,22 +121,18 @@ static int parse_string(AVIOContext *pb, int *cur_byte, AVBPrint *bp, int full) } ret = expect_byte(pb, cur_byte, '"'); if (ret < 0) - goto fail; - if (full && !av_bprint_is_complete(bp)) { - ret = AVERROR(ENOMEM); - goto fail; - } - return 0; + return ret; + if (full && !av_bprint_is_complete(bp)) + return AVERROR(ENOMEM); -fail: - av_bprint_finalize(bp, NULL); - return ret; + return 0; } static int parse_label(AVIOContext *pb, int *cur_byte, AVBPrint *bp) { int ret; + av_bprint_init(bp, 0, AV_BPRINT_SIZE_AUTOMATIC); ret = parse_string(pb, cur_byte, bp, 0); if (ret < 0) return ret; @@ -181,6 +172,8 @@ static int parse_int(AVIOContext *pb, int *cur_byte, int64_t *result) if ((unsigned)*cur_byte - '0' > 9) return AVERROR_INVALIDDATA; while (BETWEEN(*cur_byte, '0', '9')) { + if (val > INT_MAX/10 - (*cur_byte - '0')) + return AVERROR_INVALIDDATA; val = val * 10 + (*cur_byte - '0'); next_byte(pb, cur_byte); } @@ -195,6 +188,8 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) int64_t pos, start, duration; AVPacket *pkt; + av_bprint_init(&content, 0, AV_BPRINT_SIZE_UNLIMITED); + next_byte(pb, &cur_byte); ret = expect_byte(pb, &cur_byte, '{'); if (ret < 0) @@ -206,34 +201,34 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) if (ret < 0) return AVERROR_INVALIDDATA; while (1) { - content.size = 0; start = duration = AV_NOPTS_VALUE; ret = expect_byte(pb, &cur_byte, '{'); if (ret < 0) - return ret; + goto fail; pos = avio_tell(pb) - 1; while (1) { ret = parse_label(pb, &cur_byte, &label); if (ret < 0) - return ret; + goto fail; if (!strcmp(label.str, "startOfParagraph")) { ret = parse_boolean(pb, &cur_byte, &start_of_par); if (ret < 0) - return ret; + goto fail; } else if (!strcmp(label.str, "content")) { ret = parse_string(pb, &cur_byte, &content, 1); if (ret < 0) - return ret; + goto fail; } else if (!strcmp(label.str, "startTime")) { ret = parse_int(pb, &cur_byte, &start); if (ret < 0) - return ret; + goto fail; } else if (!strcmp(label.str, "duration")) { ret = parse_int(pb, &cur_byte, &duration); if (ret < 0) - return ret; + goto fail; } else { - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } skip_spaces(pb, &cur_byte); if (cur_byte != ',') @@ -242,18 +237,22 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) } ret = expect_byte(pb, &cur_byte, '}'); if (ret < 0) - return ret; + goto fail; if (!content.size || start == AV_NOPTS_VALUE || - duration == AV_NOPTS_VALUE) - return AVERROR_INVALIDDATA; + duration == AV_NOPTS_VALUE) { + ret = AVERROR_INVALIDDATA; + goto fail; + } pkt = ff_subtitles_queue_insert(subs, content.str, content.len, 0); - if (!pkt) - return AVERROR(ENOMEM); + if (!pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } pkt->pos = pos; pkt->pts = start; pkt->duration = duration; - av_bprint_finalize(&content, NULL); + av_bprint_clear(&content); skip_spaces(pb, &cur_byte); if (cur_byte != ',') @@ -262,23 +261,28 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) } ret = expect_byte(pb, &cur_byte, ']'); if (ret < 0) - return ret; + goto fail; ret = expect_byte(pb, &cur_byte, '}'); if (ret < 0) - return ret; + goto fail; skip_spaces(pb, &cur_byte); if (cur_byte != AVERROR_EOF) - return ERR_CODE(cur_byte); - return 0; + ret = ERR_CODE(cur_byte); +fail: + av_bprint_finalize(&content, NULL); + return ret; } static av_cold int tedcaptions_read_header(AVFormatContext *avf) { TEDCaptionsDemuxer *tc = avf->priv_data; - AVStream *st; + AVStream *st = avformat_new_stream(avf, NULL); int ret, i; AVPacket *last; + if (!st) + return AVERROR(ENOMEM); + ret = parse_file(avf->pb, &tc->subs); if (ret < 0) { if (ret == AVERROR_INVALIDDATA) @@ -289,12 +293,9 @@ static av_cold int tedcaptions_read_header(AVFormatContext *avf) } ff_subtitles_queue_finalize(avf, &tc->subs); for (i = 0; i < tc->subs.nb_subs; i++) - tc->subs.subs[i].pts += tc->start_time; + tc->subs.subs[i]->pts += tc->start_time; - last = &tc->subs.subs[tc->subs.nb_subs - 1]; - st = avformat_new_stream(avf, NULL); - if (!st) - return AVERROR(ENOMEM); + last = tc->subs.subs[tc->subs.nb_subs - 1]; st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_TEXT; avpriv_set_pts_info(st, 64, 1, 1000); @@ -321,7 +322,7 @@ static int tedcaptions_read_close(AVFormatContext *avf) return 0; } -static av_cold int tedcaptions_read_probe(AVProbeData *p) +static av_cold int tedcaptions_read_probe(const AVProbeData *p) { static const char *const tags[] = { "\"captions\"", "\"duration\"", "\"content\"", @@ -353,7 +354,7 @@ static int tedcaptions_read_seek(AVFormatContext *avf, int stream_index, min_ts, ts, max_ts, flags); } -AVInputFormat ff_tedcaptions_demuxer = { +const AVInputFormat ff_tedcaptions_demuxer = { .name = "tedcaptions", .long_name = NULL_IF_CONFIG_SMALL("TED Talks captions"), .priv_data_size = sizeof(TEDCaptionsDemuxer),