summaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorchcunningham <chcunningham@chromium.org>2019-02-07 14:58:17 -0800
committerMichael Niedermayer <michael@niedermayer.cc>2019-02-08 12:00:59 +0100
commit1c15449ca9a5bfa387868ac55628397273da761f (patch)
tree8dd4fa4ffc0a2c571172ec108d429e47b66c3ced /libavformat
parent3ea87e5d9ea075d5b3c0f4f8c6c48e514b454cbe (diff)
downloadffmpeg-streaming-1c15449ca9a5bfa387868ac55628397273da761f.zip
ffmpeg-streaming-1c15449ca9a5bfa387868ac55628397273da761f.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>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/mov.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 6afb656..cc91beb 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2697,8 +2697,11 @@ static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int in
if (mov_stsc_index_valid(index, sc->stsc_count))
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 * (int64_t)chunk_count;
}
@@ -4170,6 +4173,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))) ||
@@ -4178,7 +4188,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;
OpenPOWER on IntegriCloud