1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

Merge remote-tracking branch 'tjoppen/fuzz_fixes'

* tjoppen/fuzz_fixes:
  mxfdec: Don't crash in mxf_packet_timestamps() if current_edit_unit overflows
  mxfdec: Zero nb_ptses in mxf_compute_ptses_fake_index()
  mxfdec: Sanity check PreviousPartition
  mxfdec: Never seek back in local sets and KLVs
  mxfdec: Move the current_partition check inside mxf_read_header()
  mxfdec: Fix infinite loop in mxf_packet_timestamps()
  mxfdec: Check url_feof() in mxf_read_local_tags()
  mxfdec: Check for NULL component

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-12-22 14:04:42 +01:00
commit dd1fb65287

View File

@ -479,6 +479,13 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size
partition->previous_partition, footer_partition, partition->previous_partition, footer_partition,
partition->index_sid, partition->body_sid); partition->index_sid, partition->body_sid);
/* sanity check PreviousPartition if set */
if (partition->previous_partition &&
mxf->run_in + partition->previous_partition >= klv_offset) {
av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition points to this partition or forward\n");
return AVERROR_INVALIDDATA;
}
if (op[12] == 1 && op[13] == 1) mxf->op = OP1a; if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b; else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;
else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c; else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;
@ -1021,8 +1028,10 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
for (i = 0; i < index_table->nb_segments; i++) { for (i = 0; i < index_table->nb_segments; i++) {
MXFIndexTableSegment *s = index_table->segments[i]; MXFIndexTableSegment *s = index_table->segments[i];
if (!s->nb_index_entries) if (!s->nb_index_entries) {
index_table->nb_ptses = 0;
return 0; /* no TemporalOffsets */ return 0; /* no TemporalOffsets */
}
index_table->nb_ptses += s->index_duration; index_table->nb_ptses += s->index_duration;
} }
@ -1276,7 +1285,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
break; break;
} }
} }
if (!source_track) if (!source_track || !component)
continue; continue;
if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) { if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
@ -1437,7 +1446,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF
if (!ctx) if (!ctx)
return -1; return -1;
while (avio_tell(pb) + 4 < klv_end) { while (avio_tell(pb) + 4 < klv_end && !url_feof(pb)) {
int tag = avio_rb16(pb); int tag = avio_rb16(pb);
int size = avio_rb16(pb); /* KLV specified by 0x53 */ int size = avio_rb16(pb); /* KLV specified by 0x53 */
uint64_t next = avio_tell(pb) + size; uint64_t next = avio_tell(pb) + size;
@ -1464,6 +1473,13 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF
else if (read_child(ctx, pb, tag, size, uid, -1) < 0) else if (read_child(ctx, pb, tag, size, uid, -1) < 0)
return -1; return -1;
/* accept the 64k local set limit being exceeded (Avid)
* don't accept it extending past the end of the KLV though (zzuf5.mxf) */
if (avio_tell(pb) > klv_end) {
av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x extends past end of local set @ %#"PRIx64"\n",
tag, klv->offset);
return AVERROR_INVALIDDATA;
} else if (avio_tell(pb) <= next) /* only seek forward, else this can loop for a long time */
avio_seek(pb, next, SEEK_SET); avio_seek(pb, next, SEEK_SET);
} }
if (ctx_size) ctx->type = type; if (ctx_size) ctx->type = type;
@ -1500,11 +1516,6 @@ static int mxf_parse_handle_essence(MXFContext *mxf)
AVIOContext *pb = mxf->fc->pb; AVIOContext *pb = mxf->fc->pb;
int64_t ret; int64_t ret;
if (!mxf->current_partition) {
av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to PartitionPack\n");
return AVERROR_INVALIDDATA;
}
if (mxf->parsing_backward) { if (mxf->parsing_backward) {
return mxf_seek_to_previous_partition(mxf); return mxf_seek_to_previous_partition(mxf);
} else { } else {
@ -1620,6 +1631,12 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
IS_KLV_KEY(klv.key, mxf_essence_element_key) || IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) || IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) ||
IS_KLV_KEY(klv.key, mxf_system_item_key)) { IS_KLV_KEY(klv.key, mxf_system_item_key)) {
if (!mxf->current_partition) {
av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to first PartitionPack\n");
return AVERROR_INVALIDDATA;
}
if (!mxf->current_partition->essence_offset) { if (!mxf->current_partition->essence_offset) {
/* for OP1a we compute essence_offset /* for OP1a we compute essence_offset
* for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25) * for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25)
@ -1666,6 +1683,14 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
} else { } else {
uint64_t next = avio_tell(s->pb) + klv.length; uint64_t next = avio_tell(s->pb) + klv.length;
res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset); res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
/* only seek forward, else this can loop for a long time */
if (avio_tell(s->pb) > next) {
av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
klv.offset);
return AVERROR_INVALIDDATA;
}
avio_seek(s->pb, next, SEEK_SET); avio_seek(s->pb, next, SEEK_SET);
} }
if (res < 0) { if (res < 0) {
@ -1712,7 +1737,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
*/ */
static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt) static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt)
{ {
int64_t next_ofs; int64_t last_ofs = -1, next_ofs;
MXFIndexTable *t = &mxf->index_tables[0]; MXFIndexTable *t = &mxf->index_tables[0];
/* this is called from the OP1a demuxing logic, which means there may be no index tables */ /* this is called from the OP1a demuxing logic, which means there may be no index tables */
@ -1720,17 +1745,25 @@ static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt)
return; return;
/* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */ /* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */
for (;;) { while (mxf->current_edit_unit >= 0) {
if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0) if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0)
break; break;
if (next_ofs <= last_ofs) {
/* large next_ofs didn't change or current_edit_unit wrapped around
* this fixes the infinite loop on zzuf3.mxf */
av_log(mxf->fc, AV_LOG_ERROR, "next_ofs didn't change. not deriving packet timestamps\n");
return;
}
if (next_ofs > pkt->pos) if (next_ofs > pkt->pos)
break; break;
last_ofs = next_ofs;
mxf->current_edit_unit++; mxf->current_edit_unit++;
} }
if (mxf->current_edit_unit >= t->nb_ptses) if (mxf->current_edit_unit < 0 || mxf->current_edit_unit >= t->nb_ptses)
return; return;
pkt->dts = mxf->current_edit_unit + t->first_dts; pkt->dts = mxf->current_edit_unit + t->first_dts;