demux: mkv: don't use EbmlDummy elements coming out of FindNextID()
authorSteve Lhomme <robux4@ycbcr.xyz>
Tue, 26 Nov 2024 05:33:48 +0000 (06:33 +0100)
committerSebastian Ramacher <sramacher@debian.org>
Tue, 21 Jan 2025 18:02:47 +0000 (19:02 +0100)
FindNextID() is supposed to return an element of the given type when it's found. But in some cases,
when the ID and sizes are plausible, an EbmlDummy is returned [1].

We should not use that element as if it was a legit element we're looking for.
This is especially crucial when we're opening a file to decide if it's an EBML file or not (EbmlHead).

[1] https://github.com/Matroska-Org/libebml/blob/1c4e2f31b8df7f2c137d8943c73385759aae35b9/src/EbmlElement.cpp#L185

(cherry picked from commit 49d4586fe82aa105ebc1f519e8c8b7385f89c211)

Gbp-Pq: Name 0107-demux-mkv-don-t-use-EbmlDummy-elements-coming-out-of.patch

modules/demux/mkv/demux.cpp
modules/demux/mkv/matroska_segment.cpp

index 154deb00528efef889bba8c5ddb0dcfbd7dc5859..74b23d8d043a42443eca6f3f64d40cc7d039f15a 100644 (file)
@@ -458,9 +458,10 @@ bool demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, matroska_stream_c *
 
     /* verify the EBML Header... it shouldn't be bigger than 1kB */
     p_l0 = p_stream1->estream.FindNextID(EBML_INFO(EbmlHead), 1024);
-    if (p_l0 == NULL)
+    if (p_l0 == nullptr || p_l0->IsDummy())
     {
         msg_Err( p_demux, "No EBML header found" );
+        delete p_l0;
         return false;
     }
 
@@ -494,13 +495,14 @@ bool demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, matroska_stream_c *
 
     // find all segments in this file
     p_l0 = p_stream1->estream.FindNextID(EBML_INFO(KaxSegment), UINT64_MAX);
-    if (p_l0 == NULL)
+    if (p_l0 == nullptr || p_l0->IsDummy())
     {
         msg_Err( p_demux, "No segment found" );
+        delete p_l0;
         return false;
     }
 
-    while (p_l0 != 0)
+    while (p_l0 != nullptr)
     {
         bool b_l0_handled = false;
 
@@ -535,10 +537,15 @@ bool demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, matroska_stream_c *
         {
             p_l0->SkipData(p_stream1->estream, KaxMatroska_Context);
             p_l0 = p_stream1->estream.FindNextID(EBML_INFO(KaxSegment), UINT64_MAX);
+            if (p_l0 != nullptr && p_l0->IsDummy())
+            {
+                delete p_l0;
+                p_l0 = nullptr;
+            }
         }
         else
         {
-            p_l0 = NULL;
+            p_l0 = nullptr;
         }
 
         if( b_l0_handled == false )
index 4fb30452c9083436bf97048c49597b13dcb42bf0..82689f69d92d4ce9044cdbc870395c58fb82fd8c 100644 (file)
@@ -713,10 +713,11 @@ bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int
     es.I_O().setFilePointer( i_element_position, seek_beginning );
     el = es.FindNextID( ClassInfos, 0xFFFFFFFFL);
 
-    if( el == NULL )
+    if( el == nullptr || el->IsDummy() )
     {
         msg_Err( &sys.demuxer, "cannot load some cues/chapters/tags etc. (broken seekhead or file)" );
         es.I_O().setFilePointer( i_sav_position, seek_beginning );
+        delete el;
         return false;
     }