diff options
author | Tomas Härdin <git@haerdin.se> | 2024-10-14 16:45:35 +0200 |
---|---|---|
committer | Tomas Härdin <git@haerdin.se> | 2024-10-21 11:14:24 +0200 |
commit | baa23e40c190ad0afdc2398e60d4da2aacc86ad9 (patch) | |
tree | 8f83583c89482cdc28c1344f41e8077c0947ce7e | |
parent | b61141056939acfd67e51dbd05c2c8c729d6b31b (diff) | |
download | ffmpeg-baa23e40c190ad0afdc2398e60d4da2aacc86ad9.tar.gz |
lavf/mxfdec: Set a scan direction explicitly
This prevents a theoretical case where seeks to a gap in an index can cause an infinite loop
-rw-r--r-- | libavformat/mxfdec.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index e5f59089ab..27e8e0c261 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1907,7 +1907,7 @@ static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid) /* EditUnit -> absolute offset */ static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, AVRational edit_rate, int64_t *edit_unit_out, int64_t *offset_out, MXFPartition **partition_out, int nag) { - int i = 0; + int i = 0, dir = 0; int64_t index_duration, index_end; MXFIndexTableSegment *first_segment, *last_segment; @@ -1939,7 +1939,7 @@ static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_t i = FFMAX(0, FFMIN(index_table->nb_segments - 1, i64)); } - for (; i >= 0 && i < index_table->nb_segments;) { + for (; i >= 0 && i < index_table->nb_segments; i += dir) { MXFIndexTableSegment *s = index_table->segments[i]; if (s->index_start_position <= edit_unit && edit_unit < s->index_start_position + s->index_duration) { @@ -1969,12 +1969,14 @@ static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_t *edit_unit_out = av_rescale_q(edit_unit, edit_rate, s->index_edit_rate); return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out, partition_out); - } else if (edit_unit < s->index_start_position) { - // the segments are sorted by IndexStartPosition, so this is guaranteed to terminate - i--; - } else { - // edit_unit >= s->index_start_position + s->index_duration - i++; + } else if (dir == 0) { + // scan backwards if the segment is earlier than the current IndexStartPosition + // else scan forwards + if (edit_unit < s->index_start_position) { + dir = -1; + } else { + dir = 1; + } } } |