diff options
Diffstat (limited to 'lib/ffmpeg/libavformat/matroskadec.c')
-rw-r--r-- | lib/ffmpeg/libavformat/matroskadec.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/lib/ffmpeg/libavformat/matroskadec.c b/lib/ffmpeg/libavformat/matroskadec.c index 5473f89051..1a87f4a0c6 100644 --- a/lib/ffmpeg/libavformat/matroskadec.c +++ b/lib/ffmpeg/libavformat/matroskadec.c @@ -538,8 +538,8 @@ static int ebml_level_end(MatroskaDemuxContext *matroska) static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, int max_size, uint64_t *number) { - int len_mask = 0x80, read = 1, n = 1; - int64_t total = 0; + int read = 1, n = 1; + uint64_t total = 0; /* The first byte tells us the length in bytes - get_byte() can normally * return 0, but since that's not a valid first ebmlID byte, we can @@ -556,10 +556,7 @@ static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, } /* get the length of the EBML number */ - while (read <= max_size && !(total & len_mask)) { - read++; - len_mask >>= 1; - } + read = 8 - ff_log2_tab[total]; if (read > max_size) { int64_t pos = url_ftell(pb) - 1; av_log(matroska->ctx, AV_LOG_ERROR, @@ -569,7 +566,7 @@ static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, } /* read out length */ - total &= ~len_mask; + total ^= 1 << ff_log2_tab[total]; while (n++ < read) total = (total << 8) | get_byte(pb); @@ -578,6 +575,20 @@ static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, return read; } +/** + * Read a EBML length value. + * This needs special handling for the "unknown length" case which has multiple + * encodings. + */ +static int ebml_read_length(MatroskaDemuxContext *matroska, ByteIOContext *pb, + uint64_t *number) +{ + int res = ebml_read_num(matroska, pb, 8, number); + if (res > 0 && *number + 1 == 1ULL << (7 * res)) + *number = 0xffffffffffffffULL; + return res; +} + /* * Read the next element as an unsigned int. * 0 is success, < 0 is failure. @@ -586,7 +597,7 @@ static int ebml_read_uint(ByteIOContext *pb, int size, uint64_t *num) { int n = 0; - if (size < 1 || size > 8) + if (size > 8) return AVERROR_INVALIDDATA; /* big-endian ordering; build up number */ @@ -603,7 +614,9 @@ static int ebml_read_uint(ByteIOContext *pb, int size, uint64_t *num) */ static int ebml_read_float(ByteIOContext *pb, int size, double *num) { - if (size == 4) { + if (size == 0) { + *num = 0; + } else if (size == 4) { *num= av_int2flt(get_be32(pb)); } else if(size==8){ *num= av_int2dbl(get_be64(pb)); @@ -783,7 +796,7 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska, if (syntax->type != EBML_PASS && syntax->type != EBML_STOP) { matroska->current_id = 0; - if ((res = ebml_read_num(matroska, pb, 8, &length)) < 0) + if ((res = ebml_read_length(matroska, pb, &length)) < 0) return res; } @@ -901,6 +914,9 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size, int result = 0; int olen; + if (pkt_size >= 10000000) + return -1; + switch (encodings[0].compression.algo) { case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: return encodings[0].compression.settings.size; @@ -1017,6 +1033,11 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, for (i=0; i < list->nb_elem; i++) { const char *lang = strcmp(tags[i].lang, "und") ? tags[i].lang : NULL; + + if (!tags[i].name) { + av_log(s, AV_LOG_WARNING, "Skipping invalid tag with no TagName.\n"); + continue; + } if (prefix) snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name); else av_strlcpy(key, tags[i].name, sizeof(key)); if (tags[i].def || !lang) { @@ -1032,6 +1053,7 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, matroska_convert_tag(s, &tags[i].sub, metadata, key); } } + ff_metadata_conv(metadata, NULL, ff_mkv_metadata_conv); } static void matroska_convert_tags(AVFormatContext *s) @@ -1435,10 +1457,6 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec->channels = track->audio.channels; if (st->codec->codec_id != CODEC_ID_AAC) st->need_parsing = AVSTREAM_PARSE_HEADERS; - if (st->codec->codec_id == CODEC_ID_DTS) { - st->need_parsing = AVSTREAM_PARSE_FULL; - st->codec->channels = 0; - } } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; } @@ -1735,7 +1753,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int offset = 0, pkt_size = lace_size[n]; uint8_t *pkt_data = data; - if (lace_size[n] > size) { + if (pkt_size > size) { av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n"); break; } @@ -1902,14 +1920,13 @@ static int matroska_read_close(AVFormatContext *s) return 0; } -AVInputFormat matroska_demuxer = { - "matroska", - NULL_IF_CONFIG_SMALL("Matroska file format"), +AVInputFormat ff_matroska_demuxer = { + "matroska,webm", + NULL_IF_CONFIG_SMALL("Matroska/WebM file format"), sizeof(MatroskaDemuxContext), matroska_probe, matroska_read_header, matroska_read_packet, matroska_read_close, matroska_read_seek, - .metadata_conv = ff_mkv_metadata_conv, }; |