@@ -203,20 +203,38 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
}
}
- if (!ret && timeslen == fileposlen)
+ if (!ret && timeslen == fileposlen && fileposlen > 1 &&
+ max_pos <= filepositions[0]) {
+ int64_t dts, size0, size1;
+ /* Seek back to the end of the index (instead to before it)
+ * afterwards, since we parsed it successfully. */
+ initial_pos = avio_tell(ioc);
+ avio_seek(ioc, filepositions[1] - 4, SEEK_SET);
+ size0 = avio_rb32(ioc);
+ avio_r8(ioc);
+ size1 = avio_rb24(ioc);
+ dts = avio_rb24(ioc);
+ dts |= avio_r8(ioc) << 24;
+ /* A quick index sanity check: size0, the size of the packet
+ * preceding the second index entry, should be less than the
+ * file position. The timestamp of the packet should be
+ * within 5 seconds from what the index claimed it to be.
+ * Anything else indicates an incorrectly interpreted or simply
+ * broken index.
+ */
+ if (size0 > filepositions[1] || FFABS(dts - times[1]*1000) > 5000)
+ goto finish;
for (i = 0; i < fileposlen; i++)
av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME);
- else
+ } else
av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
finish:
av_freep(×);
av_freep(&filepositions);
- // If we got unexpected data, but successfully reset back to
- // the start pos, the caller can continue parsing
- if (ret < 0 && avio_seek(ioc, initial_pos, SEEK_SET) > 0)
- return 0;
- return ret;
+ if (avio_seek(ioc, initial_pos, SEEK_SET) != initial_pos)
+ return ret ? ret : AVERROR(EIO);
+ return 0;
}
static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
From: Michael Niedermayer <michaelni@gmx.at> This avoids adding index entries for files where the index is defined in an incompatible way, or where it simply is broken. This requires doing a short seek to the second index entry to validate the index, and thus we need to seek back at the end of the parsing function, even if we were able to parse the whole index successfully. --- libavformat/flvdec.c | 32 +++++++++++++++++++++++++------- 1 files changed, 25 insertions(+), 7 deletions(-)