libwebm: handle unknown cluster size in Segment::Load too

Change-Id: I7ed5feb7fe29cd413c8de35274138605725c5b38
diff --git a/mkvparser.cpp b/mkvparser.cpp
index f7e0b0b..99eaaeb 100644
--- a/mkvparser.cpp
+++ b/mkvparser.cpp
@@ -1769,17 +1769,33 @@
     assert(m_clusters == NULL);

     assert(m_clusterSize == 0);

     assert(m_clusterCount == 0);

-    assert(m_size >= 0);  //TODO: we now allow size < 0

+    //assert(m_size >= 0);

 

     //Outermost (level 0) segment object has been constructed,

     //and pos designates start of payload.  We need to find the

     //inner (level 1) elements.

 

-    const long long stop = m_start + m_size;

+    long long total, avail;

 

-    while (m_pos < stop)

+    const long status = m_pReader->Length(&total, &avail);

+

+    if (status < 0)  //error

+        return status;

+

+    assert((total < 0) || (avail <= total));

+

+    const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;

+

+    for (;;)

     {

         long long pos = m_pos;

+

+        if ((total >= 0) && (pos >= total))

+            break;

+

+        if ((segment_stop >= 0) && (pos >= segment_stop))

+            break;

+

         const long long element_start = pos;

 

         long len;

@@ -1789,7 +1805,7 @@
         if (result < 0)  //error

             return static_cast<long>(result);

 

-        if ((pos + len) > stop)

+        if ((segment_stop >= 0) && ((pos + len) > segment_stop))

             return E_FILE_FORMAT_INVALID;

 

         const long long idpos = pos;

@@ -1806,7 +1822,7 @@
         if (result < 0)  //error

             return static_cast<long>(result);

 

-        if ((pos + len) > stop)

+        if ((segment_stop >= 0) && ((pos + len) > segment_stop))

             return E_FILE_FORMAT_INVALID;

 

         const long long size = ReadUInt(m_pReader, pos, len);

@@ -1814,13 +1830,18 @@
         if (size < 0)  //error

             return static_cast<long>(size);

 

+        const long long unknown_size = (1LL << (7 * len)) - 1;

+

+        if (size == unknown_size)

+            return E_FILE_FORMAT_INVALID;

+

         pos += len;  //consume length of size of element

 

         const long long element_size = size + pos - element_start;

 

         //Pos now points to start of payload

 

-        if ((pos + size) > stop)

+        if ((segment_stop >= 0) && ((pos + size) > segment_stop))

             return E_FILE_FORMAT_INVALID;

 

         if (id == 0x0F43B675)  //Cluster ID

@@ -1876,8 +1897,6 @@
         m_pos = pos + size;  //consume payload

     }

 

-    assert(m_pos >= stop);

-

     if (m_pInfo == NULL)

         return E_FILE_FORMAT_INVALID;  //TODO: ignore this case?

 

@@ -5494,6 +5513,10 @@
         const long long size = ReadUInt(pReader, pos, len);

         assert(size > 0);

 

+        const long long unknown_size = (1LL << (7 * len)) - 1;

+        unknown_size;

+        assert(size != unknown_size);

+

         pos += len;  //consume size

 

         //pos now points to start of payload