aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <nfxjfg@googlemail.com>2014-12-06 16:53:30 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-12-21 04:40:35 +0100
commit437e50b3d65fecd374b56c39c55bc6d340004502 (patch)
tree3a140b37589f97ce5aa3c4596d7826834163627f
parentb3e98715c0e5d9d8d2fc467b9f2fed9aa6bb0381 (diff)
downloadffmpeg-437e50b3d65fecd374b56c39c55bc6d340004502.tar.gz
avformat/matroskadec: fix handling of recursive SeekHead elements
When matroska_execute_seekhead() is called, it goes through the list of seekhead entries and attempts to read elements not read yet. When doing this, the parser can find further SeekHead elements, and will extend the matroska->seekhead list. This can lead to a (practically) infinite loop with certain broken files. (Maybe it can happen even with valid files. The demuxer doesn't seem to check correctly whether an element has already been read.) Fix this by ignoring elements that were added to the seekhead field during executing seekhead entries. This does not fix the possible situation when multiple SeekHead elements after the file header (i.e. occur after the "before_pos" file position) point to the same elements. These elements will probably be parsed multiple times, likely leading to bugs. Fixes ticket #4162. Signed-off-by: Michael Niedermayer <michaelni@gmx.at> (cherry picked from commit 6551acab6877addae815decd02aeca33ba4990c8) Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/matroskadec.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 5f5ab91bd5..aabf4e7af3 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1346,13 +1346,17 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
EbmlList *seekhead_list = &matroska->seekhead;
int64_t before_pos = avio_tell(matroska->ctx->pb);
int i;
+ int nb_elem;
// we should not do any seeking in the streaming case
if (!matroska->ctx->pb->seekable ||
(matroska->ctx->flags & AVFMT_FLAG_IGNIDX))
return;
- for (i = 0; i < seekhead_list->nb_elem; i++) {
+ // do not read entries that are added while parsing seekhead entries
+ nb_elem = seekhead_list->nb_elem;
+
+ for (i = 0; i < nb_elem; i++) {
MatroskaSeekhead *seekhead = seekhead_list->elem;
if (seekhead[i].pos <= before_pos)
continue;