diff options
author | chcunningham <chcunningham@chromium.org> | 2019-02-07 14:58:17 -0800 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2019-03-24 10:39:03 +0100 |
commit | 750ec96f667811d32f4a6044db333419b12d79c2 (patch) | |
tree | 9605531995cecb6f42fe5fd584b3caccaa569e7f | |
parent | 90c194710a6610a6d596877c3f53a11a0cc3a65a (diff) | |
download | ffmpeg-750ec96f667811d32f4a6044db333419b12d79c2.tar.gz |
avformat/mov: validate chunk_count vs stsc_data
Bad content may contain stsc boxes with a first_chunk index that
exceeds stco.entries (chunk_count). This ammends the existing check to
include cases where chunk_count == 0. It also patches up the case
when stsc refers to unknown chunks, but stts has no samples (so we
can simply ignore stsc).
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 1c15449ca9a5bfa387868ac55628397273da761f)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/mov.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index ae7ef19927..f22a407f49 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2459,8 +2459,11 @@ static inline int mov_get_stsc_samples(MOVStreamContext *sc, int index) if (index < sc->stsc_count - 1) chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first; - else + else { + // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak. + av_assert0(sc->stsc_data[index].first <= sc->chunk_count); chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1); + } return sc->stsc_data[index].count * chunk_count; } @@ -3635,6 +3638,13 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) c->trak_index = -1; + // Here stsc refers to a chunk not described in stco. This is technically invalid, + // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples). + if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) { + sc->stsc_count = 0; + av_freep(&sc->stsc_data); + } + /* sanity checks */ if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count || (!sc->sample_size && !sc->sample_count))) { @@ -3642,7 +3652,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->index); return 0; } - if (sc->chunk_count && sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) { + if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) { av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n", st->index); return AVERROR_INVALIDDATA; |