[vlc-commits] demux:mkv: remove the internal recursion when dummy data are encountered

Steve Lhomme git at videolan.org
Tue Jan 23 10:09:01 CET 2018


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Jan 23 10:08:28 2018 +0100| [91d894e762de634170edaa70e423d8950aea2407] | committer: Steve Lhomme

demux:mkv: remove the internal recursion when dummy data are encountered

There was an issue with who is responsible to delete the previous element in
the call stack. With a double free in some cases.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=91d894e762de634170edaa70e423d8950aea2407
---

 modules/demux/mkv/Ebml_parser.cpp | 35 +++++++++++++++++++++++++++++------
 modules/demux/mkv/Ebml_parser.hpp |  2 +-
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/modules/demux/mkv/Ebml_parser.cpp b/modules/demux/mkv/Ebml_parser.cpp
index 29cf6b3d30..61c2eddd30 100644
--- a/modules/demux/mkv/Ebml_parser.cpp
+++ b/modules/demux/mkv/Ebml_parser.cpp
@@ -137,9 +137,10 @@ const EbmlSemanticContext Context_KaxSegmentVLC = EbmlSemanticContext(KaxSegment
                                                                       GetEbmlNoGlobal_Context,
                                                                       KaxSegment_Context.GetMaster());
 
-EbmlElement *EbmlParser::Get( int n_call )
+EbmlElement *EbmlParser::Get()
 {
     int i_ulev = 0;
+    int n_call = 0;
     EbmlElement *p_prev = NULL;
 
     if( mi_user_level != mi_level )
@@ -209,7 +210,10 @@ next:
     if( m_el[mi_level] == NULL )
     {
         if ( i_max_read != UINT64_MAX && !static_cast<vlc_stream_io_callback *>(&m_es->I_O())->IsEOF() )
-            i_ulev = 1; /* found nothing valid anymore at this level, go up */
+        {
+            msg_Dbg(p_demux, "found nothing, go up");
+            i_ulev = 1;
+        }
     }
 
     if( i_ulev > 0 )
@@ -275,6 +279,17 @@ next:
             /* The element fits inside its upper element */
             msg_Warn( p_demux, "Dummy element found %" PRIu64 "... skipping it",
                       m_el[mi_level]->GetElementPosition() );
+            if( p_prev )
+            {
+                if( !mb_keep )
+                {
+                    if( MKV_IS_ID( p_prev, KaxBlockVirtual ) )
+                        static_cast<KaxBlockVirtualWorkaround*>(p_prev)->Fix(); // !! WARNING : TODO !! this is undefined-behavior
+                    delete p_prev;
+                    p_prev = NULL;
+                }
+                mb_keep = false;
+            }
             n_call++;
             goto next;
         }
@@ -297,10 +312,18 @@ next:
                 return NULL;
             }
 
-            EbmlElement *unwanted_dummy = m_el[mi_level];
-            EbmlElement *upper_dummy = Get();
-            delete unwanted_dummy;
-            return upper_dummy;
+            if( p_prev )
+            {
+                if( !mb_keep )
+                {
+                    if( MKV_IS_ID( p_prev, KaxBlockVirtual ) )
+                        static_cast<KaxBlockVirtualWorkaround*>(p_prev)->Fix(); // !! WARNING : TODO !! this is undefined-behavior
+                    delete p_prev;
+                    p_prev = NULL;
+                }
+                mb_keep = false;
+            }
+            goto next;
         }
     }
 
diff --git a/modules/demux/mkv/Ebml_parser.hpp b/modules/demux/mkv/Ebml_parser.hpp
index 320b1f5d08..20e0d4e80b 100644
--- a/modules/demux/mkv/Ebml_parser.hpp
+++ b/modules/demux/mkv/Ebml_parser.hpp
@@ -43,7 +43,7 @@ class EbmlParser
     void Up( void );
     void Down( void );
     void Reset( demux_t *p_demux );
-    EbmlElement *Get( int n_call = 0 );
+    EbmlElement *Get( void );
     void        Keep( void );
     void        Unkeep( void );
 



More information about the vlc-commits mailing list