[vlc-commits] [Git][videolan/vlc][3.0.x] 5 commits: contrib: ebml: avoid reading more than 2^32 at once
Steve Lhomme (@robUx4)
gitlab at videolan.org
Wed May 20 08:16:51 UTC 2026
Steve Lhomme pushed to branch 3.0.x at VideoLAN / VLC
Commits:
736eab6b by Steve Lhomme at 2026-05-20T06:19:08+00:00
contrib: ebml: avoid reading more than 2^32 at once
Backport for a patch on the master branch.
(cherry picked from commit c79852da80b1f87c56a75a1de2b8f25687ba6751)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
7fc6c00b by Steve Lhomme at 2026-05-20T06:19:08+00:00
contrib: ebml: fix early parent check
We can only check it if both elements are not infinite.
Fixes #29833
(cherry picked from commit 2a679fe52d87aeca53b2fa41a0cde4329c93d6dd)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
a41815e5 by Steve Lhomme at 2026-05-20T06:19:08+00:00
contrib: matroska: fix reading EBML lacing with just one frame
The spec [^1] is not clear whether when there is a single frame in the lace
the size of the frame should be written. However it is forbidden to put
a single frame in a lace [^2]. libmatroska doesn't support it.
libavformat doesn't support lacing writing.
However the last frame size is never written in any lace, so that's the
first one when there's only one frame.
Fixes #29832
[^1]: https://www.rfc-editor.org/rfc/rfc9559#section-10.3.3
[^2]: https://www.rfc-editor.org/rfc/rfc9559#section-10.3
(cherry picked from commit 6f3c40871388ecdc3f1171acbeaec94c4bfd017e)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
992b727b by Steve Lhomme at 2026-05-20T06:19:08+00:00
contrib: matroska: expand FrameNum after reading
Fixes #29834
(cherry picked from commit 6032a6a89ad4a11fe0b1d7745d5f948e41380d86)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
4cfd1153 by Steve Lhomme at 2026-05-20T06:19:08+00:00
demux: mkv: avoid potential constant overflow
We never use this code to start reading an EBML/Matroska stream but better safe
than sorry.
CID #1692707
(cherry picked from commit 8e209b172e3d53503e45294d525cd2b287a62bb2)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
9 changed files:
- + contrib/src/ebml/0001-IOCallback-avoid-reading-more-than-2-32-at-once.patch
- contrib/src/ebml/0002-EbmlMaster-exit-reading-loop-if-upper-element-found-.patch
- contrib/src/ebml/rules.mak
- + contrib/src/matroska/0001-KaxBlock-expand-FrameNum-after-reading.patch
- contrib/src/matroska/0001-KaxBlock-rework-EBML-lacing-sizes-in-SCOPE_PARTIAL_D.patch
- contrib/src/matroska/0002-KaxBlock-throw-when-the-EBML-length-difference-gives.patch
- + contrib/src/matroska/0003-KaxBlock-fix-reading-EBML-lacing-with-just-one-frame.patch
- contrib/src/matroska/rules.mak
- modules/demux/mkv/Ebml_parser.cpp
Changes:
=====================================
contrib/src/ebml/0001-IOCallback-avoid-reading-more-than-2-32-at-once.patch
=====================================
@@ -0,0 +1,51 @@
+From 1a8c6d1e2518fe19d1d1d206b6df03470abb8e09 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <slhomme at matroska.org>
+Date: Sun, 2 Oct 2022 09:24:27 +0200
+Subject: [PATCH] IOCallback: avoid reading more than 2^32 at once
+
+In practice it should never happen as 2^32+1 buffers are not possible on any
+known platform. But better safe than sorry. Or memory mapped files could reach
+this code ?
+
+(cherry picked from commit 40b4797829f6a35c1ea0a160ba7feed7443acb7d)
+---
+ src/IOCallback.cpp | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/src/IOCallback.cpp b/src/IOCallback.cpp
+index 13ed635..4fbaeee 100644
+--- a/src/IOCallback.cpp
++++ b/src/IOCallback.cpp
+@@ -33,6 +33,7 @@
+ \author Moritz Bunkus <moritz @ bunkus.org>
+ */
+
++#include <limits>
+ #include <sstream>
+ #include <stdexcept>
+
+@@ -64,10 +65,17 @@ void IOCallback::readFully(void*Buffer,size_t Size)
+ if(Buffer == nullptr)
+ throw;
+
+- if(read(Buffer,Size) != Size) {
+- stringstream Msg;
+- Msg<<"EOF in readFully("<<Buffer<<","<<Size<<")";
+- throw runtime_error(Msg.str());
++ char *readBuf = static_cast<char *>(Buffer);
++ uint32_t readSize = static_cast<uint32_t>(std::min<size_t>(std::numeric_limits<uint32>::max(), Size));
++ while (readSize != 0) {
++ if(read(readBuf,readSize) != readSize) {
++ stringstream Msg;
++ Msg<<"EOF in readFully("<<Buffer<<","<<Size<<")";
++ throw runtime_error(Msg.str());
++ }
++ Size -= readSize;
++ readBuf += readSize;
++ readSize = static_cast<uint32_t>(std::min<size_t>(std::numeric_limits<uint32>::max(), Size));
+ }
+ }
+
+--
+2.52.0.windows.1
+
=====================================
contrib/src/ebml/0002-EbmlMaster-exit-reading-loop-if-upper-element-found-.patch
=====================================
@@ -1,4 +1,4 @@
-From e78fb38d6cfef3a8bc5eb7e39f4c210d291f0787 Mon Sep 17 00:00:00 2001
+From 50fba837fa4ebdd9b3c46f71a952873ae569cd48 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
@@ -11,19 +11,19 @@ And we shouldn't use a MaxSizeToRead that would be negative.
1 file changed, 3 insertions(+)
diff --git a/src/EbmlMaster.cpp b/src/EbmlMaster.cpp
-index e8a43cc..9dc291a 100644
+index e8a43cc..6f03432 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)
+@@ -454,6 +454,9 @@ void EbmlMaster::Read(EbmlStream & inDataStream, const EbmlSemanticContext & sCo
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()) {
++ if (ElementLevelA->GetEndPosition() > GetEndPosition()) {
++ goto processCrc; // found an upper element that ends after this, we were truncated
++ }
MaxSizeToRead = GetEndPosition() - ElementLevelA->GetEndPosition(); // even if it's the default value
}
+ continue;
--
2.52.0.windows.1
=====================================
contrib/src/ebml/rules.mak
=====================================
@@ -14,6 +14,7 @@ $(TARBALLS)/libebml-$(EBML_VERSION).tar.xz:
ebml: libebml-$(EBML_VERSION).tar.xz .sum-ebml
$(UNPACK)
+ $(APPLY) $(SRC)/ebml/0001-IOCallback-avoid-reading-more-than-2-32-at-once.patch
$(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
=====================================
contrib/src/matroska/0001-KaxBlock-expand-FrameNum-after-reading.patch
=====================================
@@ -0,0 +1,41 @@
+From fd4cfd9f04fa6fba4f1ac9ecc9b68930e40056ec Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Tue, 12 May 2026 07:59:51 +0200
+Subject: [PATCH] KaxBlock: expand FrameNum after reading
+
+It's read as a uint8_t. Adding 1 to 255 would end up being 0.
+---
+ src/KaxBlock.cpp | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/KaxBlock.cpp b/src/KaxBlock.cpp
+index 7bcc879..b3f2a84 100644
+--- a/src/KaxBlock.cpp
++++ b/src/KaxBlock.cpp
+@@ -496,9 +496,9 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+ } else {
+ // read the number of frames in the lace
+ uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
+- const uint8 FrameNum = Mem.GetUInt8(); // number of frames in the lace - 1
++ const unsigned FrameNum = Mem.GetUInt8(); // number of frames in the lace - 1
+ // read the list of frame sizes
+- uint8 Index;
++ unsigned Index;
+ int32 FrameSize;
+ uint32 SizeRead;
+ uint64 SizeUnknown;
+@@ -628,9 +628,9 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+ // read the number of frames in the lace
+ const uint32 TotalLacedSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
+ uint32 LastBufferSize = TotalLacedSize;
+- const uint8 FrameNum = _TempHead[0]; // number of frames in the lace - 1
++ const unsigned FrameNum = _TempHead[0]; // number of frames in the lace - 1
+ // read the list of frame sizes
+- uint8 Index;
++ unsigned Index;
+ uint32 FrameSize;
+ uint32 SizeRead;
+ uint64 SizeUnknown;
+--
+2.52.0.windows.1
+
=====================================
contrib/src/matroska/0001-KaxBlock-rework-EBML-lacing-sizes-in-SCOPE_PARTIAL_D.patch
=====================================
@@ -1,7 +1,7 @@
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
+Subject: [PATCH 1/3] KaxBlock: rework EBML lacing sizes in SCOPE_PARTIAL_DATA
mode
We only read the bytes that correspond to frame sizes, rather
=====================================
contrib/src/matroska/0002-KaxBlock-throw-when-the-EBML-length-difference-gives.patch
=====================================
@@ -1,7 +1,7 @@
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
+Subject: [PATCH 2/3] KaxBlock: throw when the EBML length difference gives a
negative frame length
---
=====================================
contrib/src/matroska/0003-KaxBlock-fix-reading-EBML-lacing-with-just-one-frame.patch
=====================================
@@ -0,0 +1,43 @@
+From 66e4f59d325afc159b7a1e05683dd8b8698459ea Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Mon, 11 May 2026 09:43:20 +0200
+Subject: [PATCH 3/3] KaxBlock: fix reading EBML lacing with just one frame
+
+The spec [^1] is not clear whether when there is a single frame in the lace
+the size of the frame should be written. However it is forbidden to put
+a single frame in a lace [^2]. libmatroska doesn't support it.
+libavformat doesn't support lacing writing.
+However the last frame size is never written in any lace, so that's the
+first one when there's only one frame.
+
+[^1]: https://www.rfc-editor.org/rfc/rfc9559#section-10.3.3
+[^2]: https://www.rfc-editor.org/rfc/rfc9559#section-10.3
+---
+ src/KaxBlock.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/KaxBlock.cpp b/src/KaxBlock.cpp
+index ddf8b14..eccb4c7 100644
+--- a/src/KaxBlock.cpp
++++ b/src/KaxBlock.cpp
+@@ -683,6 +683,9 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+ throw SafeReadIOCallback::EndOfStreamX(0);
+ };
+
++ if (FrameNum == 0)
++ Index = 0;
++ else {
+ binary length_buf[8];
+ if (input.read(length_buf, 1) != 1)
+ throw SafeReadIOCallback::EndOfStreamX(0);
+@@ -723,6 +726,7 @@ filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
+ SizeList[Index] = FrameSize;
+ LastBufferSize -= FrameSize + SizeRead;
+ }
++ }
+
+ SizeList[Index] = LastBufferSize;
+ break;
+--
+2.52.0.windows.1
+
=====================================
contrib/src/matroska/rules.mak
=====================================
@@ -23,6 +23,8 @@ matroska: libmatroska-$(MATROSKA_VERSION).tar.xz .sum-matroska
$(APPLY) $(SRC)/matroska/0001-KaxBlock-release-read-buffers-on-EndOfStream-error.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
+ $(APPLY) $(SRC)/matroska/0003-KaxBlock-fix-reading-EBML-lacing-with-just-one-frame.patch
+ $(APPLY) $(SRC)/matroska/0001-KaxBlock-expand-FrameNum-after-reading.patch
$(MOVE)
.matroska: matroska toolchain.cmake
=====================================
modules/demux/mkv/Ebml_parser.cpp
=====================================
@@ -220,7 +220,7 @@ next:
// If the parent is a segment, use the segment context when creating children
// (to prolong their lifetime), otherwise just continue as normal
EbmlSemanticContext e_context =
- EBML_CTX_MASTER( EBML_CONTEXT(m_el[mi_level - 1]) ) == EBML_CTX_MASTER( Context_KaxSegmentVLC )
+ (mi_level == 0 || EBML_CTX_MASTER( EBML_CONTEXT(m_el[mi_level - 1]) ) == EBML_CTX_MASTER( Context_KaxSegmentVLC ))
? Context_KaxSegmentVLC
: EBML_CONTEXT(m_el[mi_level - 1]);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0f8da0df35b32f6c0d844f9f27cdf4ac300dfa98...4cfd11539510243a2c5096761cb6d292a1578a01
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0f8da0df35b32f6c0d844f9f27cdf4ac300dfa98...4cfd11539510243a2c5096761cb6d292a1578a01
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the vlc-commits
mailing list