summaryrefslogtreecommitdiff
path: root/libavformat/mov.c
diff options
context:
space:
mode:
authorSasi Inguva <isasi@google.com>2017-10-18 20:11:16 -0700
committerMichael Niedermayer <michael@niedermayer.cc>2017-10-28 20:24:04 +0200
commit80137531139588774e048d6e1dae34ab5cbbbfa2 (patch)
tree98ebd7ea2feb6c852ef0ca6983cc19e320ab840d /libavformat/mov.c
parent8edb9d457251c190f7ad9de764981f79eb113374 (diff)
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.c21
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);