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.
This commit is contained in:
@@ -1035,14 +1035,19 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
sc->chunk_count = entries;
|
sc->chunk_count = entries;
|
||||||
|
|
||||||
if (atom.type == MKTAG('s','t','c','o'))
|
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);
|
sc->chunk_offsets[i] = avio_rb32(pb);
|
||||||
else if (atom.type == MKTAG('c','o','6','4'))
|
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);
|
sc->chunk_offsets[i] = avio_rb64(pb);
|
||||||
else
|
else
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
sc->chunk_count = i;
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
return 0;
|
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];
|
st = c->fc->streams[c->fc->nb_streams-1];
|
||||||
sc = st->priv_data;
|
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
|
//Parsing Sample description table
|
||||||
enum AVCodecID id;
|
enum AVCodecID id;
|
||||||
int dref_id = 1;
|
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);
|
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)
|
if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
|
||||||
st->codec->sample_rate= sc->time_scale;
|
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));
|
sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
|
||||||
if (!sc->stsc_data)
|
if (!sc->stsc_data)
|
||||||
return AVERROR(ENOMEM);
|
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].first = avio_rb32(pb);
|
||||||
sc->stsc_data[i].count = avio_rb32(pb);
|
sc->stsc_data[i].count = avio_rb32(pb);
|
||||||
sc->stsc_data[i].id = avio_rb32(pb);
|
sc->stsc_data[i].id = avio_rb32(pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc->stsc_count = i;
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
return 0;
|
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));
|
sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data));
|
||||||
if (!sc->stps_data)
|
if (!sc->stps_data)
|
||||||
return AVERROR(ENOMEM);
|
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);
|
sc->stps_data[i] = avio_rb32(pb);
|
||||||
//av_dlog(c->fc, "stps %d\n", sc->stps_data[i]);
|
//av_dlog(c->fc, "stps %d\n", sc->stps_data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc->stps_count = i;
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1524,12 +1543,17 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
sc->keyframes = av_malloc(entries * sizeof(int));
|
sc->keyframes = av_malloc(entries * sizeof(int));
|
||||||
if (!sc->keyframes)
|
if (!sc->keyframes)
|
||||||
return AVERROR(ENOMEM);
|
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);
|
sc->keyframes[i] = avio_rb32(pb);
|
||||||
//av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
|
//av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc->keyframe_count = i;
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
return 0;
|
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);
|
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->sample_sizes[i] = get_bits_long(&gb, field_size);
|
||||||
sc->data_size += sc->sample_sizes[i];
|
sc->data_size += sc->sample_sizes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc->sample_count = i;
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
av_free(buf);
|
av_free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1634,9 +1663,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
if (!sc->stts_data)
|
if (!sc->stts_data)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
sc->stts_count = entries;
|
for (i = 0; i < entries && !pb->eof_reached; i++) {
|
||||||
|
|
||||||
for (i=0; i<entries; i++) {
|
|
||||||
int sample_duration;
|
int sample_duration;
|
||||||
int sample_count;
|
int sample_count;
|
||||||
|
|
||||||
@@ -1652,6 +1679,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
total_sample_count+=sample_count;
|
total_sample_count+=sample_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc->stts_count = i;
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
st->nb_frames= total_sample_count;
|
st->nb_frames= total_sample_count;
|
||||||
if (duration)
|
if (duration)
|
||||||
st->duration= 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));
|
sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
|
||||||
if (!sc->ctts_data)
|
if (!sc->ctts_data)
|
||||||
return AVERROR(ENOMEM);
|
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 count =avio_rb32(pb);
|
||||||
int duration =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->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);
|
av_dlog(c->fc, "dts shift %d\n", sc->dts_shift);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2252,7 +2288,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
offset = frag->base_data_offset + data_offset;
|
offset = frag->base_data_offset + data_offset;
|
||||||
distance = 0;
|
distance = 0;
|
||||||
av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags);
|
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;
|
unsigned sample_size = frag->size;
|
||||||
int sample_flags = i ? frag->flags : first_sample_flags;
|
int sample_flags = i ? frag->flags : first_sample_flags;
|
||||||
unsigned sample_duration = frag->duration;
|
unsigned sample_duration = frag->duration;
|
||||||
@@ -2283,6 +2319,10 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
offset += sample_size;
|
offset += sample_size;
|
||||||
sc->data_size += sample_size;
|
sc->data_size += sample_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pb->eof_reached)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
frag->moof_offset = offset;
|
frag->moof_offset = offset;
|
||||||
st->duration = sc->track_end = dts + sc->time_offset;
|
st->duration = sc->track_end = dts + sc->time_offset;
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user