diff options
author | Sasi Inguva <isasi@google.com> | 2017-10-18 20:11:16 -0700 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2017-10-28 20:24:04 +0200 |
commit | 80137531139588774e048d6e1dae34ab5cbbbfa2 (patch) | |
tree | 98ebd7ea2feb6c852ef0ca6983cc19e320ab840d /libavformat/mov.c | |
parent | 8edb9d457251c190f7ad9de764981f79eb113374 (diff) | |
download | ffmpeg-80137531139588774e048d6e1dae34ab5cbbbfa2.tar.gz |
lavf/mov.c: Fix parsing of edit list atoms with invalid elst entry count.
Signed-off-by: Sasi Inguva <isasi@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r-- | libavformat/mov.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 2ee67561e4..209b7470a9 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4852,6 +4852,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) { MOVStreamContext *sc; int i, edit_count, version; + int64_t elst_entry_size; if (c->fc->nb_streams < 1 || c->ignore_editlist) return 0; @@ -4860,6 +4861,21 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) version = avio_r8(pb); /* version */ avio_rb24(pb); /* flags */ edit_count = avio_rb32(pb); /* entries */ + atom.size -= 8; + + elst_entry_size = version == 1 ? 20 : 12; + if (atom.size != edit_count * elst_entry_size) { + if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) { + av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n", + edit_count, atom.size + 8); + return AVERROR_INVALIDDATA; + } else { + edit_count = atom.size / elst_entry_size; + if (edit_count * elst_entry_size != atom.size) { + av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count); + } + } + } if (!edit_count) return 0; @@ -4872,17 +4888,20 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR(ENOMEM); av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count); - for (i = 0; i < edit_count && !pb->eof_reached; i++) { + for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) { MOVElst *e = &sc->elst_data[i]; if (version == 1) { e->duration = avio_rb64(pb); e->time = avio_rb64(pb); + atom.size -= 16; } else { e->duration = avio_rb32(pb); /* segment duration */ e->time = (int32_t)avio_rb32(pb); /* media time */ + atom.size -= 8; } e->rate = avio_rb32(pb) / 65536.0; + atom.size -= 4; av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n", e->duration, e->time, e->rate); |