[vlc-commits] Avoid inifite loops and stack explosion when parsing broken files and ignore lvl 1 unknown elements .
Denis Charmet
git at videolan.org
Fri Jan 11 01:33:31 CET 2013
vlc | branch: master | Denis Charmet <typx at dinauz.org> | Fri Jan 11 00:53:56 2013 +0100| [127c9329ac47fbbf5ff6509b6c8f8c338cba17d9] | committer: Denis Charmet
Avoid inifite loops and stack explosion when parsing broken files and ignore lvl 1 unknown elements.
Fix #8013
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=127c9329ac47fbbf5ff6509b6c8f8c338cba17d9
---
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 2283e92..43038b3 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]) );
More information about the vlc-commits
mailing list