diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2012-09-16 20:32:12 +0200 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2012-09-18 15:32:52 +0200 |
commit | 9888ffb1ce5e0a17f711b01933d504c72ea29d3b (patch) | |
tree | a973b67e0948fbcc1dacd0f606f06bc89c0e83fc | |
parent | 419ffb239074dbe1ff3c2a2debc95ca48ee42268 (diff) | |
download | ffmpeg-9888ffb1ce5e0a17f711b01933d504c72ea29d3b.tar.gz |
mov: check for EOF in long lasting loops
A quite widespread pattern in the demuxer is read a 32bit unsigned
integer and then loop till this value is reached.
Checking for EOF prevents pathological situations.
-rw-r--r-- | libavformat/mov.c | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 87c890ebfc..56a075e0b0 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1035,14 +1035,19 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->chunk_count = entries; if (atom.type == MKTAG('s','t','c','o')) - for (i=0; i<entries; i++) + for (i = 0; i < entries && !pb->eof_reached; i++) sc->chunk_offsets[i] = avio_rb32(pb); else if (atom.type == MKTAG('c','o','6','4')) - for (i=0; i<entries; i++) + for (i = 0; i < entries && !pb->eof_reached; i++) sc->chunk_offsets[i] = avio_rb64(pb); else return AVERROR_INVALIDDATA; + sc->chunk_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + return 0; } @@ -1092,7 +1097,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) st = c->fc->streams[c->fc->nb_streams-1]; sc = st->priv_data; - for (pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) { + for (pseudo_stream_id = 0; + pseudo_stream_id < entries && !pb->eof_reached; + pseudo_stream_id++) { //Parsing Sample description table enum AVCodecID id; int dref_id = 1; @@ -1361,6 +1368,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) avio_skip(pb, a.size); } + if (pb->eof_reached) + return AVERROR_EOF; + if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) st->codec->sample_rate= sc->time_scale; @@ -1457,13 +1467,18 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data)); if (!sc->stsc_data) return AVERROR(ENOMEM); - sc->stsc_count = entries; - for (i=0; i<entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { sc->stsc_data[i].first = avio_rb32(pb); sc->stsc_data[i].count = avio_rb32(pb); sc->stsc_data[i].id = avio_rb32(pb); } + + sc->stsc_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + return 0; } @@ -1486,13 +1501,17 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data)); if (!sc->stps_data) return AVERROR(ENOMEM); - sc->stps_count = entries; - for (i = 0; i < entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { sc->stps_data[i] = avio_rb32(pb); //av_dlog(c->fc, "stps %d\n", sc->stps_data[i]); } + sc->stps_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + return 0; } @@ -1524,12 +1543,17 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->keyframes = av_malloc(entries * sizeof(int)); if (!sc->keyframes) return AVERROR(ENOMEM); - sc->keyframe_count = entries; - for (i=0; i<entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { sc->keyframes[i] = avio_rb32(pb); //av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]); } + + sc->keyframe_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + return 0; } @@ -1596,11 +1620,16 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) init_get_bits(&gb, buf, 8*num_bytes); - for (i = 0; i < entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { sc->sample_sizes[i] = get_bits_long(&gb, field_size); sc->data_size += sc->sample_sizes[i]; } + sc->sample_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + av_free(buf); return 0; } @@ -1634,9 +1663,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!sc->stts_data) return AVERROR(ENOMEM); - sc->stts_count = entries; - - for (i=0; i<entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { int sample_duration; int sample_count; @@ -1652,6 +1679,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) total_sample_count+=sample_count; } + sc->stts_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + st->nb_frames= total_sample_count; if (duration) st->duration= duration; @@ -1683,9 +1715,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data)); if (!sc->ctts_data) return AVERROR(ENOMEM); - sc->ctts_count = entries; - for (i=0; i<entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { int count =avio_rb32(pb); int duration =avio_rb32(pb); @@ -1695,6 +1726,11 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->dts_shift = FFMAX(sc->dts_shift, -duration); } + sc->ctts_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + av_dlog(c->fc, "dts shift %d\n", sc->dts_shift); return 0; @@ -2252,7 +2288,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) offset = frag->base_data_offset + data_offset; distance = 0; av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags); - for (i = 0; i < entries; i++) { + for (i = 0; i < entries && !pb->eof_reached; i++) { unsigned sample_size = frag->size; int sample_flags = i ? frag->flags : first_sample_flags; unsigned sample_duration = frag->duration; @@ -2283,6 +2319,10 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) offset += sample_size; sc->data_size += sample_size; } + + if (pb->eof_reached) + return AVERROR_EOF; + frag->moof_offset = offset; st->duration = sc->track_end = dts + sc->time_offset; return 0; |