vlc/vlc-2.0 | branch: master | Denis Charmet <[email protected]> | Fri Jan 11 00:53:56 2013 +0100| [2eada7f9901648e05ce6ed432fcc988d40e7da6f] | committer: Jean-Baptiste Kempf
Avoid inifite loops and stack explosion when parsing broken files and ignore lvl 1 unknown elements. Fix #8013 (cherry picked from commit 127c9329ac47fbbf5ff6509b6c8f8c338cba17d9) Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=2eada7f9901648e05ce6ed432fcc988d40e7da6f --- modules/demux/mkv/Ebml_parser.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/modules/demux/mkv/Ebml_parser.cpp b/modules/demux/mkv/Ebml_parser.cpp index 64c6705..461fda3 100644 --- a/modules/demux/mkv/Ebml_parser.cpp +++ b/modules/demux/mkv/Ebml_parser.cpp @@ -166,9 +166,11 @@ EbmlElement *EbmlParser::Get( int n_call ) } vlc_stream_io_callback & io_stream = (vlc_stream_io_callback &) m_es->I_O(); uint64 i_size = io_stream.toRead(); + + /* Ignore unknown level 0 or 1 elements */ m_el[mi_level] = m_es->FindNextElement( EBML_CONTEXT(m_el[mi_level - 1]), - i_ulev, i_size, true, 1 ); -// mi_remain_size[mi_level] = m_el[mi_level]->GetSize(); + i_ulev, i_size, + ( mb_dummy | (mi_level > 1) ), 1 ); if( i_ulev > 0 ) { if( p_prev ) @@ -214,7 +216,8 @@ EbmlElement *EbmlParser::Get( int n_call ) } if( p_prev && p_prev->IsFiniteSize() && - p_prev->GetEndPosition() != m_el[mi_level]->GetElementPosition()) + p_prev->GetEndPosition() != m_el[mi_level]->GetElementPosition() && + mi_level > 1 ) { msg_Err( p_demux, "Dummy Element at unexpected position... corrupted file?" ); b_bad_position = true; @@ -225,13 +228,29 @@ EbmlElement *EbmlParser::Get( int n_call ) m_el[mi_level]->GetEndPosition() <= m_el[mi_level-1]->GetEndPosition() ) ) { /* The element fits inside its upper element */ - msg_Warn( p_demux, "Dummy element found... skipping it" ); + msg_Warn( p_demux, "Dummy element found %"PRIu64"... skipping it", + m_el[mi_level]->GetElementPosition() ); return Get( ++n_call ); } else { /* Too large, misplaced or 10 successive dummy elements */ - msg_Err( p_demux, "Dummy element too large or misplaced... skipping to next upper element" ); + msg_Err( p_demux, + "Dummy element too large or misplaced at %"PRIu64"... skipping to next upper element", + m_el[mi_level]->GetElementPosition() ); + + if( mi_level >= 1 && + m_el[mi_level]->GetElementPosition() >= m_el[mi_level-1]->GetEndPosition() ) + { + msg_Err(p_demux, "This element is outside its known parent... upping level"); + delete m_el[mi_level - 1]; + m_got = m_el[mi_level -1] = m_el[mi_level]; + m_el[mi_level] = NULL; + + mi_level--; + return NULL; + } + delete m_el[mi_level]; m_el[mi_level] = NULL; m_el[mi_level - 1]->SkipData( *m_es, EBML_CONTEXT(m_el[mi_level - 1]) ); _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
