[vlc-commits] [Git][videolan/vlc][3.0.x] 10 commits: demux: mkv: do not allow infinite elements inside finite parents

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Thu May 7 09:25:32 UTC 2026



Felix Paul Kühne pushed to branch 3.0.x at VideoLAN / VLC


Commits:
30bab548 by Steve Lhomme at 2026-05-04T11:06:33+02:00
demux: mkv: do not allow infinite elements inside finite parents

Only Segment [^1] and Clusters [^2] are allowed to be infinite.
And they are not read through this code.
libmatroska still allows any Master element to be infinite.

Fixes #29578

[^1]: https://www.rfc-editor.org/rfc/rfc9559#section-5.1
[^2]: https://www.rfc-editor.org/rfc/rfc9559#section-5.1.3

(cherry picked from commit 85befdbe2dde588de258c5450bcfdd6b320fd305) (rebased)
rebased:
- the code around is slightly different
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
6481d9aa by Steve Lhomme at 2026-05-04T11:07:02+02:00
demux: mkv: do not SkipData on elements with an unknown size

It can loop infinitely.

Ref #29578

(cherry picked from commit ec5601c05a8cc5600f177efb474339be3ffe87f0)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
f0a39552 by Steve Lhomme at 2026-05-04T11:07:02+02:00
contrib: ebml: do not allow infinite size on the EBML head

This will allow false detection of an invalid EBML header.

Submitted upstream [^1] but will need a new release as it might break the ABI.

Ref. #29578

[^1]: https://github.com/Matroska-Org/libebml/pull/328

(cherry picked from commit a8da8dcb3e1a20b706ce5d57da11e812cbf77da3)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
dd6d8a41 by Steve Lhomme at 2026-05-04T11:07:02+02:00
contrib: matroska: do not allow infinite sizes on most Master elements

This will allow false detection of an EBML elements.
Only Segment [^1] and Clusters [^2] are allowed to be infinite
and they use a different macro.

Submitted upstream [^3] but will need a new release as it might break the ABI.

Ref. #29578

[^1]: https://www.rfc-editor.org/rfc/rfc9559#section-5.1
[^2]: https://www.rfc-editor.org/rfc/rfc9559#section-5.1.3
[^3]: https://github.com/Matroska-Org/libmatroska/pull/234

(cherry picked from commit f2d8e617c8112a190e674d133676f46c69c34e01)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
d48b2df7 by Steve Lhomme at 2026-05-04T11:07:02+02:00
contrib: matroska: rework EBML lacing partial reading

We shouldn't read more than the size of EBML lacing size(s).
And we should especially not guesstimate the EBML lacing size will take.
It usually much less than the guesstimate.

(cherry picked from commit 82fd41938885196b345f492e0c411d9194bb3405)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
d3b0e154 by Steve Lhomme at 2026-05-04T11:07:02+02:00
demux: mkv: only keep the first ChapterSegmentUUID

If it's present it must be unique. We keep the last value as done for other items
and to keep the same behavior as before.

Fixes #29577

(cherry picked from commit 0d2139e3bc25084081b7f3f8cc53402bad928b7e)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
e445006c by Steve Lhomme at 2026-05-04T11:07:02+02:00
demux: mkv: only keep the first ChapterSegmentEditionUUID

If it's present it must be unique. We keep the last value as done for other items
and to keep the same behavior as before.

(cherry picked from commit 2481b45cf0e6e48722ef7650cfb6b4e92fa8aa2b)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
0b21c130 by Steve Lhomme at 2026-05-04T11:07:02+02:00
demux: mkv: initialize the element we pass as the fallback output

The element "returned" in that variable should always be a new element,
but since it's using the value we pass in the code it's better to initialize it.

(cherry picked from commit cec1b35a13ded1939eb3a55b4f5d1e92420ae904) (edited)
edited:
- in 3.0 the ReadMaster method is not inlined
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
c86e4f5e by Steve Lhomme at 2026-05-04T11:07:02+02:00
contrib: ebml: update to 1.4.5

(cherry picked from commit 41425cf356d3529e768b117b1b7da6df0c23d177) (rebased)
rebased:
- VLC 3 doesn't use https
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
cae669e4 by Steve Lhomme at 2026-05-04T11:12:11+02:00
contrib: ebml: exit reading loop if upper element found ends after its parent

It could be a file with missing data in the middle.
And we shouldn't use a MaxSizeToRead that would be negative.

(cherry picked from commit 83f6a75a17904013ac3df1da9f8d3baf8293a8f8)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -


13 changed files:

- + contrib/src/ebml/0001-EbmlHead-do-not-allow-to-have-an-infinite-unknown-si.patch
- contrib/src/ebml/0001-EbmlMaster-fix-leak-when-reading-upper-level-element.patch
- + contrib/src/ebml/0002-EbmlMaster-exit-reading-loop-if-upper-element-found-.patch
- contrib/src/ebml/SHA512SUMS
- contrib/src/ebml/rules.mak
- − contrib/src/matroska/0001-KaxBlock-fix-leak-when-reading-EBML-lace-is-aborted.patch
- + contrib/src/matroska/0001-KaxBlock-rework-EBML-lacing-sizes-in-SCOPE_PARTIAL_D.patch
- + contrib/src/matroska/0001-KaxDefines-do-not-allow-infinite-sizes-on-all-Master.patch
- + contrib/src/matroska/0002-KaxBlock-throw-when-the-EBML-length-difference-gives.patch
- contrib/src/matroska/rules.mak
- modules/demux/mkv/Ebml_parser.cpp
- modules/demux/mkv/matroska_segment.cpp
- modules/demux/mkv/matroska_segment_parse.cpp


Changes:

=====================================
contrib/src/ebml/0001-EbmlHead-do-not-allow-to-have-an-infinite-unknown-si.patch
=====================================
@@ -0,0 +1,28 @@
+From 4ad8d9335f593d767f319b61ba5dc531fb2c3e52 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 25 Jul 2025 14:37:18 +0200
+Subject: [PATCH] EbmlHead: do not allow to have an infinite/unknown size
+
+It does not have [^1]  unknownsizeallowed set to true (default to false)
+
+[^1]: https://www.rfc-editor.org/rfc/rfc8794.html#section-11.2.1
+---
+ ebml/EbmlHead.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ebml/EbmlHead.h b/ebml/EbmlHead.h
+index b575b79..9768b5f 100644
+--- a/ebml/EbmlHead.h
++++ b/ebml/EbmlHead.h
+@@ -46,6 +46,8 @@ DECLARE_EBML_MASTER(EbmlHead)
+     EbmlHead(const EbmlHead & ElementToClone)  = default;
+ 
+         EBML_CONCRETE_CLASS(EbmlHead)
++
++    bool SetSizeInfinite(bool finite = true) override { return !finite; }
+ };
+ 
+ } // namespace libebml
+-- 
+2.52.0.windows.1
+


=====================================
contrib/src/ebml/0001-EbmlMaster-fix-leak-when-reading-upper-level-element.patch
=====================================
@@ -1,7 +1,7 @@
-From 3660273b4a6b71f9678da744f86a2035fd98fcc2 Mon Sep 17 00:00:00 2001
+From fd2b70256e8e4b35a62a90bfae2ca48e0996d5a2 Mon Sep 17 00:00:00 2001
 From: Steve Lhomme <robux4 at ycbcr.xyz>
 Date: Fri, 25 Jul 2025 14:37:18 +0200
-Subject: [PATCH] EbmlMaster: fix leak when reading upper level elements
+Subject: [PATCH 1/2] EbmlMaster: fix leak when reading upper level elements
 
 When an element from an upper level is found we go up the caller chain,
 passing the found element but it was not actually used (added to a list or freed).
@@ -14,19 +14,15 @@ The new MaxSizeToRead is the size to read in the next inDataStream.FindNextEleme
 The old MaxSizeToRead <= 0 code seems bogus as it would exit the loop
 to find elements for that EbmlMaster even though there might still be elements to read.
 ---
- src/EbmlMaster.cpp | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
+ src/EbmlMaster.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
 
 diff --git a/src/EbmlMaster.cpp b/src/EbmlMaster.cpp
-index 071eb5d..465560f 100644
+index faadfd0..e8a43cc 100644
 --- a/src/EbmlMaster.cpp
 +++ b/src/EbmlMaster.cpp
-@@ -455,9 +455,12 @@ void EbmlMaster::Read(EbmlStream & inDataStream, const EbmlSemanticContext & sCo
- 
-       if (UpperEltFound > 0) {
-         UpperEltFound--;
--        if (UpperEltFound > 0 || MaxSizeToRead <= 0)
-+        if (UpperEltFound > 0)
+@@ -453,6 +453,9 @@ void EbmlMaster::Read(EbmlStream & inDataStream, const EbmlSemanticContext & sCo
+         if (UpperEltFound > 0 || MaxSizeToRead == 0)
            goto processCrc;
          ElementLevelA = FoundElt;
 +        if (IsFiniteSize() && ElementLevelA->IsFiniteSize()) {
@@ -36,5 +32,5 @@ index 071eb5d..465560f 100644
        }
  
 -- 
-2.45.1.windows.1
+2.52.0.windows.1
 


=====================================
contrib/src/ebml/0002-EbmlMaster-exit-reading-loop-if-upper-element-found-.patch
=====================================
@@ -0,0 +1,29 @@
+From e78fb38d6cfef3a8bc5eb7e39f4c210d291f0787 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Thu, 30 Apr 2026 16:28:00 +0200
+Subject: [PATCH 2/2] EbmlMaster: exit reading loop if upper element found ends
+ after its parent
+
+It could be a file with missing data in the middle.
+And we shouldn't use a MaxSizeToRead that would be negative.
+---
+ src/EbmlMaster.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/EbmlMaster.cpp b/src/EbmlMaster.cpp
+index e8a43cc..9dc291a 100644
+--- a/src/EbmlMaster.cpp
++++ b/src/EbmlMaster.cpp
+@@ -453,6 +453,9 @@ void EbmlMaster::Read(EbmlStream & inDataStream, const EbmlSemanticContext & sCo
+         if (UpperEltFound > 0 || MaxSizeToRead == 0)
+           goto processCrc;
+         ElementLevelA = FoundElt;
++        if (ElementLevelA->GetEndPosition() > GetEndPosition()) {
++          goto processCrc; // found an upper element that ends after this, we were truncated
++        }
+         if (IsFiniteSize() && ElementLevelA->IsFiniteSize()) {
+           MaxSizeToRead = GetEndPosition() - ElementLevelA->GetEndPosition(); // even if it's the default value
+         }
+-- 
+2.52.0.windows.1
+


=====================================
contrib/src/ebml/SHA512SUMS
=====================================
@@ -1 +1 @@
-6a7a544f3f5a273eaab8c71aa692492cbfb671b3d73f03ab76438843a9a7a9379f9cffdae0e1452cf064e43c10ad82424645504a23d7f3336eabcd38f2621d0a  libebml-1.4.3.tar.xz
+6ee2afd538de8b028a1acd4a0f00a8aa230deac297573d868683e96f22fa4953858d3a1d8ab414ac27757f35699e6149f0aaef6eb4d235baa79226d8f36ccb5c  libebml-1.4.5.tar.xz


=====================================
contrib/src/ebml/rules.mak
=====================================
@@ -1,6 +1,6 @@
 # ebml
 
-EBML_VERSION := 1.4.3
+EBML_VERSION := 1.4.5
 EBML_URL := http://dl.matroska.org/downloads/libebml/libebml-$(EBML_VERSION).tar.xz
 
 ifeq ($(call need_pkg,"libebml >= 1.3.8"),)
@@ -17,6 +17,8 @@ ebml: libebml-$(EBML_VERSION).tar.xz .sum-ebml
 	$(APPLY) $(SRC)/ebml/0001-EbmlString-ReadFully-use-automatic-memory-management.patch
 	$(APPLY) $(SRC)/ebml/0002-EbmlUnicodeString-use-std-string-when-reading-instea.patch
 	$(APPLY) $(SRC)/ebml/0001-EbmlMaster-fix-leak-when-reading-upper-level-element.patch
+	$(APPLY) $(SRC)/ebml/0002-EbmlMaster-exit-reading-loop-if-upper-element-found-.patch
+	$(APPLY) $(SRC)/ebml/0001-EbmlHead-do-not-allow-to-have-an-infinite-unknown-si.patch
 	$(MOVE)
 
 .ebml: ebml toolchain.cmake


=====================================
contrib/src/matroska/0001-KaxBlock-fix-leak-when-reading-EBML-lace-is-aborted.patch deleted
=====================================
@@ -1,59 +0,0 @@
-From 6d2ad6dfb9d16a7747cc8395b022fc20eb91d3ec Mon Sep 17 00:00:00 2001
-From: Steve Lhomme <slhomme at matroska.org>
-Date: Fri, 24 Oct 2025 11:18:54 +0200
-Subject: [PATCH 1/2] KaxBlock: fix leak when reading EBML lace is aborted
-
----
- src/KaxBlock.cpp | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/src/KaxBlock.cpp b/src/KaxBlock.cpp
-index 62b0947..6a61b73 100644
---- a/src/KaxBlock.cpp
-+++ b/src/KaxBlock.cpp
-@@ -44,6 +44,8 @@
- #include "matroska/KaxCluster.h"
- #include "matroska/KaxDefines.h"
- 
-+#include <memory>
-+
- namespace libmatroska {
- 
- DataBuffer * DataBuffer::Clone()
-@@ -582,7 +584,6 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
-       if (Result != 5)
-         throw SafeReadIOCallback::EndOfStreamX(0);
-       binary *cursor = _TempHead;
--      binary *_tmpBuf;
-       uint8 BlockHeadSize = 4;
- 
-       // update internal values
-@@ -656,8 +657,10 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
-             SizeList[Index] = LastBufferSize;
-             break;
-           case LACING_EBML:
-+          {
-             SizeRead = LastBufferSize;
--            cursor = _tmpBuf = new binary[FrameNum*4]; /// \warning assume the mean size will be coded in less than 4 bytes
-+            auto _tmpBuf = std::make_unique<binary>(FrameNum*4); /// \warning assume the mean size will be coded in less than 4 bytes
-+            cursor = _tmpBuf.get();
-             Result += input.read(cursor, FrameNum*4);
-             FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
-             if (FrameSize > TotalLacedSize)
-@@ -677,11 +680,11 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
-               LastBufferSize -= FrameSize + SizeRead;
-             }
- 
--            FirstFrameLocation += cursor - _tmpBuf;
-+            FirstFrameLocation += cursor - _tmpBuf.get();
- 
-             SizeList[Index] = LastBufferSize;
--            delete [] _tmpBuf;
-             break;
-+          }
-           case LACING_FIXED:
-             for (Index=0; Index<=FrameNum; Index++) {
-               // get the size of the frame
--- 
-2.52.0.windows.1
-


=====================================
contrib/src/matroska/0001-KaxBlock-rework-EBML-lacing-sizes-in-SCOPE_PARTIAL_D.patch
=====================================
@@ -0,0 +1,113 @@
+From 058046e606eb60fcc0ce0ef3801ed11cf7e0e997 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Tue, 28 Apr 2026 10:08:39 +0200
+Subject: [PATCH 1/2] KaxBlock: rework EBML lacing sizes in SCOPE_PARTIAL_DATA
+ mode
+
+We only read the bytes that correspond to frame sizes, rather
+than a guesstimate of how much data we are going to need.
+
+That's what the SCOPE_PARTIAL_DATA mode is about. This is already the case
+for LACING_XIPH. And we don't need a buffer allocation.
+---
+ src/KaxBlock.cpp | 63 ++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 50 insertions(+), 13 deletions(-)
+
+diff --git a/src/KaxBlock.cpp b/src/KaxBlock.cpp
+index fd37ad5..5fab622 100644
+--- a/src/KaxBlock.cpp
++++ b/src/KaxBlock.cpp
+@@ -582,7 +582,6 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+       if (Result != 5)
+         throw SafeReadIOCallback::EndOfStreamX(0);
+       binary *cursor = _TempHead;
+-      binary *_tmpBuf;
+       uint8 BlockHeadSize = 4;
+ 
+       // update internal values
+@@ -656,32 +655,70 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+             SizeList[Index] = LastBufferSize;
+             break;
+           case LACING_EBML:
+-            SizeRead = LastBufferSize;
+-            cursor = _tmpBuf = new binary[FrameNum*4]; /// \warning assume the mean size will be coded in less than 4 bytes
+-            Result += input.read(cursor, FrameNum*4);
+-            FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
++          {
++            auto EBMLCodecLength = [](binary buf) {
++              // TODO: use C23  stdc_leading_zeros_uc() as well as GCC/clang __builtin_clz()
++              // __builtin_clz(buf) - 23;
++              if (buf & 0x80)
++                return 1;
++              if (buf & 0x40)
++                return 2;
++              if (buf & 0x20)
++                return 3;
++              if (buf & 0x10)
++                return 4;
++              if (buf & 0x08)
++                return 5;
++              if (buf & 0x04)
++                return 6;
++              if (buf & 0x02)
++                return 7;
++              if (buf & 0x01)
++                return 8;
++              // invalid EBML coded length
++              throw SafeReadIOCallback::EndOfStreamX(0);
++            };
++
++            binary length_buf[8];
++            if (input.read(length_buf, 1) != 1)
++              throw SafeReadIOCallback::EndOfStreamX(0);
++
++            // get the length of the EBML coded value
++            SizeRead = EBMLCodecLength(length_buf[0]);
++            // read remaining needed bytes
++            if (SizeRead > 1 && input.read(&length_buf[1], SizeRead - 1) != SizeRead - 1)
++              throw SafeReadIOCallback::EndOfStreamX(0);
++
++            FrameSize = ReadCodedSizeValue(length_buf, SizeRead, SizeUnknown);
+             if (FrameSize > TotalLacedSize)
+               throw SafeReadIOCallback::EndOfStreamX(0);
++
++            FirstFrameLocation += SizeRead;
+             SizeList[0] = FrameSize;
+-            cursor += SizeRead;
+             LastBufferSize -= FrameSize + SizeRead;
+ 
+             for (Index=1; Index<FrameNum; Index++) {
+-              // get the size of the frame
+-              SizeRead = LastBufferSize;
+-              FrameSize += ReadCodedSizeSignedValue(cursor, SizeRead, SizeUnknown);
++              if (input.read(length_buf, 1) != 1)
++                throw SafeReadIOCallback::EndOfStreamX(0);
++
++              // get the length of the EBML coded value
++              SizeRead = EBMLCodecLength(length_buf[0]);
++              // read remaining needed bytes
++              if (SizeRead > 1 && input.read(&length_buf[1], SizeRead - 1) != SizeRead - 1)
++                throw SafeReadIOCallback::EndOfStreamX(0);
++
++              FrameSize += ReadCodedSizeSignedValue(length_buf, SizeRead, SizeUnknown);
+               if (FrameSize > TotalLacedSize)
+                 throw SafeReadIOCallback::EndOfStreamX(0);
++
++              FirstFrameLocation += SizeRead;
+               SizeList[Index] = FrameSize;
+-              cursor += SizeRead;
+               LastBufferSize -= FrameSize + SizeRead;
+             }
+ 
+-            FirstFrameLocation += cursor - _tmpBuf;
+-
+             SizeList[Index] = LastBufferSize;
+-            delete [] _tmpBuf;
+             break;
++          }
+           case LACING_FIXED:
+             for (Index=0; Index<=FrameNum; Index++) {
+               // get the size of the frame
+-- 
+2.52.0.windows.1
+


=====================================
contrib/src/matroska/0001-KaxDefines-do-not-allow-infinite-sizes-on-all-Master.patch
=====================================
@@ -0,0 +1,37 @@
+From 3c0d992c17acb32b5e57b228afac8e74eb773baf Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Mon, 27 Apr 2026 11:54:02 +0200
+Subject: [PATCH] KaxDefines: do not allow infinite sizes on all Master
+ elements except Segment+Cluster
+
+Only Segment [^1] and Clusters [^2] are allowed to be infinite.
+
+[^1]: https://www.rfc-editor.org/rfc/rfc9559#section-5.1
+[^2]: https://www.rfc-editor.org/rfc/rfc9559#section-5.1.3
+---
+ matroska/KaxDefines.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/matroska/KaxDefines.h b/matroska/KaxDefines.h
+index 7734eb4..d29f6ab 100644
+--- a/matroska/KaxDefines.h
++++ b/matroska/KaxDefines.h
+@@ -62,6 +62,7 @@
+ class MATROSKA_DLL_API x : public EbmlMaster { \
+     public: x(EBML_EXTRA_PARAM); \
+     x(const x & ElementToClone) :EbmlMaster(ElementToClone) {} \
++    bool SetSizeInfinite(bool finite = true) override { return !finite; } \
+     EBML_CONCRETE_CLASS(x)
+ 
+ #define DECLARE_MKX_MASTER_CONS(x)     DECLARE_MKX_CONTEXT(x) \
+@@ -150,6 +151,7 @@ class MATROSKA_DLL_API x : public EbmlMaster { \
+ class MATROSKA_DLL_API x : public EbmlMaster { \
+     public: x(); \
+     x(const x & ElementToClone) :EbmlMaster(ElementToClone) {} \
++    bool SetSizeInfinite(bool finite = true) override { return !finite; } \
+     EBML_CONCRETE_CLASS(x)
+ 
+ #define DECLARE_MKX_MASTER_CONS(x)     DECLARE_MKX_CONTEXT(x) \
+-- 
+2.52.0.windows.1
+


=====================================
contrib/src/matroska/0002-KaxBlock-throw-when-the-EBML-length-difference-gives.patch
=====================================
@@ -0,0 +1,43 @@
+From b4c4a7ef50b3bb8cac30975437c89a377240ef6f Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Tue, 28 Apr 2026 11:30:11 +0200
+Subject: [PATCH 2/2] KaxBlock: throw when the EBML length difference gives a
+ negative frame length
+
+---
+ src/KaxBlock.cpp | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/src/KaxBlock.cpp b/src/KaxBlock.cpp
+index 5fab622..ddf8b14 100644
+--- a/src/KaxBlock.cpp
++++ b/src/KaxBlock.cpp
+@@ -533,7 +533,11 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+             for (Index=1; Index<FrameNum; Index++) {
+               // get the size of the frame
+               SizeRead = LastBufferSize;
+-              FrameSize += ReadCodedSizeSignedValue(BufferStart + Mem.GetPosition(), SizeRead, SizeUnknown);
++              auto FrameSizeDiff = ReadCodedSizeSignedValue(BufferStart + Mem.GetPosition(), SizeRead, SizeUnknown);
++              if (FrameSizeDiff < 0 && FrameSize <= -FrameSizeDiff)
++                // invalid negative or 0 frame size
++                throw SafeReadIOCallback::EndOfStreamX(SizeRead);
++              FrameSize += FrameSizeDiff;
+               if (!FrameSize || (static_cast<uint32>(FrameSize + SizeRead) > LastBufferSize))
+                 throw SafeReadIOCallback::EndOfStreamX(SizeRead);
+               SizeList[Index] = FrameSize;
+@@ -707,7 +711,11 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+               if (SizeRead > 1 && input.read(&length_buf[1], SizeRead - 1) != SizeRead - 1)
+                 throw SafeReadIOCallback::EndOfStreamX(0);
+ 
+-              FrameSize += ReadCodedSizeSignedValue(length_buf, SizeRead, SizeUnknown);
++              auto FrameSizeDiff = ReadCodedSizeSignedValue(length_buf, SizeRead, SizeUnknown);
++              if (FrameSizeDiff < 0 && FrameSize <= -FrameSizeDiff)
++                // invalid negative or 0 frame size
++                throw SafeReadIOCallback::EndOfStreamX(0);
++              FrameSize += FrameSizeDiff;
+               if (FrameSize > TotalLacedSize)
+                 throw SafeReadIOCallback::EndOfStreamX(0);
+ 
+-- 
+2.52.0.windows.1
+


=====================================
contrib/src/matroska/rules.mak
=====================================
@@ -19,8 +19,10 @@ $(TARBALLS)/libmatroska-$(MATROSKA_VERSION).tar.xz:
 matroska: libmatroska-$(MATROSKA_VERSION).tar.xz .sum-matroska
 	$(UNPACK)
 	$(call pkg_static,"libmatroska.pc.in")
+	$(APPLY) $(SRC)/matroska/0001-KaxDefines-do-not-allow-infinite-sizes-on-all-Master.patch
 	$(APPLY) $(SRC)/matroska/0001-KaxBlock-release-read-buffers-on-EndOfStream-error.patch
-	$(APPLY) $(SRC)/matroska/0001-KaxBlock-fix-leak-when-reading-EBML-lace-is-aborted.patch
+	$(APPLY) $(SRC)/matroska/0001-KaxBlock-rework-EBML-lacing-sizes-in-SCOPE_PARTIAL_D.patch
+	$(APPLY) $(SRC)/matroska/0002-KaxBlock-throw-when-the-EBML-length-difference-gives.patch
 	$(MOVE)
 
 .matroska: matroska toolchain.cmake


=====================================
modules/demux/mkv/Ebml_parser.cpp
=====================================
@@ -147,21 +147,32 @@ EbmlElement *EbmlParser::Get( bool allow_overshoot )
         EbmlElement *ret = m_got;
         m_got = NULL;
 
-        if( mi_level > 0 && m_el[mi_level-1]->IsFiniteSize() && ret->IsFiniteSize() &&
-            ret->GetEndPosition() > m_el[mi_level-1]->GetEndPosition() )
+        if( mi_level > 0 && m_el[mi_level-1]->IsFiniteSize() )
         {
-            msg_Err( p_demux, "EBML element at %" PRIu64 " extends beyond parent boundary (%" PRIu64 " beyond %" PRIu64 ")",
-                m_el[mi_level]->GetElementPosition(), m_el[mi_level]->GetEndPosition(), m_el[mi_level-1]->GetEndPosition() );
-            delete ret;
-            m_el[mi_level] = NULL;
-            return NULL;
+            if( ret->IsFiniteSize() &&
+                ret->GetEndPosition() > m_el[mi_level-1]->GetEndPosition() )
+            {
+                msg_Err( p_demux, "EBML element at %" PRIu64 " extends beyond parent boundary (%" PRIu64 " beyond %" PRIu64 ")",
+                         ret->GetElementPosition(), ret->GetEndPosition(), m_el[mi_level-1]->GetEndPosition() );
+                delete ret;
+                m_el[mi_level] = NULL;
+                return NULL;
+            }
+            if( !ret->IsFiniteSize() )
+            {
+                msg_Err( p_demux, "Infinite EBML element %s at %" PRIu64 " inside finite parent",
+                         EBML_NAME(ret), ret->GetElementPosition() );
+                delete ret;
+                m_el[mi_level] = NULL;
+                return NULL;
+            }
         }
         return ret;
     }
 
 next:
     p_prev = m_el[mi_level];
-    if( p_prev )
+    if( p_prev && p_prev->IsFiniteSize() )
         p_prev->SkipData( *m_es, EBML_CONTEXT(p_prev) );
 
     uint64_t i_max_read;
@@ -261,7 +272,7 @@ next:
     {
         msg_Dbg( p_demux,"MKV/Ebml Parser: m_el[mi_level] == NULL" );
         /* go back to the end of the parent */
-        if( p_prev )
+        if( p_prev && p_prev->IsFiniteSize() )
             p_prev->SkipData( *m_es, EBML_CONTEXT(p_prev) );
     }
     else if( m_el[mi_level]->IsDummy() && !mb_dummy )


=====================================
modules/demux/mkv/matroska_segment.cpp
=====================================
@@ -1491,7 +1491,7 @@ bool matroska_segment_c::ReadMaster(EbmlMaster & m, ScopeMode scope)
     }
     try
     {
-        EbmlElement *el;
+        EbmlElement *el = nullptr;
         int i_upper_level = 0;
         m.Read( es, EBML_CONTEXT(&m), i_upper_level, el, true, scope );
         if (i_upper_level != 0)


=====================================
modules/demux/mkv/matroska_segment_parse.cpp
=====================================
@@ -1184,6 +1184,7 @@ void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chap
         }
         E_CASE( KaxChapterSegmentUID, uid )
         {
+            delete vars.chapters.p_segment_uid;
             vars.chapters.p_segment_uid = new KaxChapterSegmentUID( uid );
             vars.obj->b_ref_external_segments = true;
 
@@ -1191,6 +1192,7 @@ void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chap
         }
         E_CASE( KaxChapterSegmentEditionUID, euid )
         {
+            delete vars.chapters.p_segment_edition_uid;
             vars.chapters.p_segment_edition_uid = new KaxChapterSegmentEditionUID( euid );
 
             debug( vars, "ChapterSegmentEditionUID=%x",



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/77befcc4ff8ca64ba3837732dae3dca44473ce4a...cae669e4b066fbc97684113e87d12a5b034f8f23

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/77befcc4ff8ca64ba3837732dae3dca44473ce4a...cae669e4b066fbc97684113e87d12a5b034f8f23
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list