summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorDale Curtis <dalecurtis@chromium.org>2017-07-31 13:44:22 -0700
committerMichael Niedermayer <michael@niedermayer.cc>2017-09-01 00:56:32 +0200
commitf1e47f87131dd7c3718496b83911e17586e26e80 (patch)
tree6fbd5bfe220d76b13b95ff9b1ac633d00a22aa17 /libavformat
parent1a0d9b503d2e9c4278d6e93d40873dff9d191a25 (diff)
avformat/mov: Bail when invalid sample data is present.
ctts data in ffmpeg relies on the index entries array to be 1:1 with samples... yet sc->sample_count can be read directly from the 'stsz' box and index entries are only generated if a chunk count has been read from 'stco' box. Ensure that if sc->sample_count > 0, sc->chunk_count is too as a basic sanity check. Additionally we need to check that after the index is built we have the right number of entries, so we also check in mov_read_trun() that sc->sample_count == st->nb_index_entries. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/mov.c33
1 files changed, 10 insertions, 23 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 876f48d912..89b2af7597 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3755,8 +3755,9 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
c->trak_index = -1;
/* sanity checks */
- if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
- (!sc->sample_size && !sc->sample_count))) {
+ if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
+ (!sc->sample_size && !sc->sample_count))) ||
+ (!sc->chunk_count && sc->sample_count)) {
av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
st->index);
return 0;
@@ -4284,26 +4285,6 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
entries = avio_rb32(pb);
av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
- /* Always assume the presence of composition time offsets.
- * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following.
- * 1) in the initial movie, there are no samples.
- * 2) in the first movie fragment, there is only one sample without composition time offset.
- * 3) in the subsequent movie fragments, there are samples with composition time offset. */
- if (!sc->ctts_count && sc->sample_count)
- {
- /* Complement ctts table if moov atom doesn't have ctts atom. */
- ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, sizeof(*sc->ctts_data) * sc->sample_count);
- if (!ctts_data)
- return AVERROR(ENOMEM);
- /* Don't use a count greater than 1 here since it will leave a gap in
- * the ctts index which the code below relies on being sequential. */
- sc->ctts_data = ctts_data;
- for (i = 0; i < sc->sample_count; i++) {
- sc->ctts_data[sc->ctts_count].count = 1;
- sc->ctts_data[sc->ctts_count].duration = 0;
- sc->ctts_count++;
- }
- }
if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
return AVERROR_INVALIDDATA;
if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
@@ -4364,13 +4345,19 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
unsigned int size_needed = st->nb_index_entries * sizeof(*sc->ctts_data);
unsigned int request_size = size_needed > sc->ctts_allocated_size ?
FFMAX(size_needed, 2 * sc->ctts_allocated_size) : size_needed;
+ unsigned int old_ctts_size = sc->ctts_allocated_size;
ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, request_size);
if (!ctts_data) {
av_freep(&sc->ctts_data);
return AVERROR(ENOMEM);
}
-
sc->ctts_data = ctts_data;
+
+ // In case there were samples without ctts entries, ensure they get
+ // zero valued entries. This ensures clips which mix boxes with and
+ // without ctts entries don't pickup uninitialized data.
+ memset((uint8_t*)(sc->ctts_data) + old_ctts_size, 0, sc->ctts_allocated_size - old_ctts_size);
+
if (ctts_index != old_nb_index_entries) {
memmove(sc->ctts_data + ctts_index + 1, sc->ctts_data + ctts_index,
sizeof(*sc->ctts_data) * (sc->ctts_count - ctts_index));