[FFmpeg-cvslog] avformat/mov: Bail when invalid sample data is present.
Dale Curtis
git at videolan.org
Fri Sep 1 01:57:30 EEST 2017
ffmpeg | branch: master | Dale Curtis <dalecurtis at chromium.org> | Mon Jul 31 13:44:22 2017 -0700| [f1e47f87131dd7c3718496b83911e17586e26e80] | committer: Michael Niedermayer
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 at niedermayer.cc>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f1e47f87131dd7c3718496b83911e17586e26e80
---
libavformat/mov.c | 33 ++++++++++-----------------------
1 file 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));
More information about the ffmpeg-cvslog
mailing list