X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmatroskadec.c;h=0e3a6890c10c0e004ca707dd374e93a2898af83f;hb=82fd7866a3d7045c1cbd8f47651410baa001f447;hp=1ded431b801cbbfd3282808794dfb2626d7908a2;hpb=b14761d1f8372dfe558193b8b754b9f1a858077d;p=ffmpeg diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 1ded431b801..0e3a6890c10 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -68,6 +68,8 @@ #include "qtpalette.h" +#define EBML_UNKNOWN_LENGTH UINT64_MAX /* EBML unknown length, in uint64_t */ + typedef enum { EBML_NONE, EBML_UINT, @@ -869,7 +871,7 @@ static int ebml_read_length(MatroskaDemuxContext *matroska, AVIOContext *pb, { int res = ebml_read_num(matroska, pb, 8, number); if (res > 0 && *number + 1 == 1ULL << (7 * res)) - *number = 0xffffffffffffffULL; + *number = EBML_UNKNOWN_LENGTH; return res; } @@ -1049,7 +1051,7 @@ static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, break; if (!syntax[i].id && id == MATROSKA_ID_CLUSTER && matroska->num_levels > 0 && - matroska->levels[matroska->num_levels - 1].length == 0xffffffffffffff) + matroska->levels[matroska->num_levels - 1].length == EBML_UNKNOWN_LENGTH) return 0; // we reached the end of an unknown size cluster if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32) { av_log(matroska->ctx, AV_LOG_DEBUG, "Unknown entry 0x%"PRIX32"\n", id); @@ -1197,6 +1199,18 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska, length, max_lengths[syntax->type], syntax->type); return AVERROR_INVALIDDATA; } + if (matroska->num_levels > 0) { + MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1]; + AVIOContext *pb = matroska->ctx->pb; + int64_t pos = avio_tell(pb); + if (level->length != EBML_UNKNOWN_LENGTH && + (pos + length) > (level->start + level->length)) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Invalid length 0x%"PRIx64" > 0x%"PRIx64" in parent\n", + length, level->start + level->length); + return AVERROR_INVALIDDATA; + } + } } switch (syntax->type) { @@ -1598,7 +1612,7 @@ static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, ret = AVERROR_INVALIDDATA; } else { level.start = 0; - level.length = (uint64_t) -1; + level.length = EBML_UNKNOWN_LENGTH; matroska->levels[matroska->num_levels] = level; matroska->num_levels++; matroska->current_id = 0; @@ -1608,7 +1622,7 @@ static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, /* remove dummy level */ while (matroska->num_levels) { uint64_t length = matroska->levels[--matroska->num_levels].length; - if (length == (uint64_t) -1) + if (length == EBML_UNKNOWN_LENGTH) break; } } @@ -2421,6 +2435,10 @@ static int matroska_parse_tracks(AVFormatContext *s) /* we don't need any value stored in CodecPrivate. make sure that it's not exported as extradata. */ track->codec_priv.size = 0; + } else if (codec_id == AV_CODEC_ID_AV1 && track->codec_priv.size) { + /* For now, propagate only the OBUs, if any. Once libavcodec is + updated to handle isobmff style extradata this can be removed. */ + extradata_offset = 4; } track->codec_priv.size -= extradata_offset; @@ -3537,7 +3555,7 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) ret = matroska_resync(matroska, pos); } - return ret; + return 0; } static int matroska_read_seek(AVFormatContext *s, int stream_index, @@ -3927,22 +3945,19 @@ static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range) // store cue point timestamps as a comma separated list for checking subsegment alignment in // the muxer. assumes that each timestamp cannot be more than 20 characters long. - buf = av_malloc_array(s->streams[0]->nb_index_entries, 20 * sizeof(char)); + buf = av_malloc_array(s->streams[0]->nb_index_entries, 20); if (!buf) return -1; strcpy(buf, ""); for (i = 0; i < s->streams[0]->nb_index_entries; i++) { - int ret = snprintf(buf + end, 20 * sizeof(char), - "%" PRId64, s->streams[0]->index_entries[i].timestamp); + int ret = snprintf(buf + end, 20, + "%" PRId64"%s", s->streams[0]->index_entries[i].timestamp, + i != s->streams[0]->nb_index_entries - 1 ? "," : ""); if (ret <= 0 || (ret == 20 && i == s->streams[0]->nb_index_entries - 1)) { av_log(s, AV_LOG_ERROR, "timestamp too long.\n"); av_free(buf); return AVERROR_INVALIDDATA; } end += ret; - if (i != s->streams[0]->nb_index_entries - 1) { - strncat(buf, ",", sizeof(char)); - end++; - } } av_dict_set(&s->streams[0]->metadata, CUE_TIMESTAMPS, buf, 0); av_free(buf);