From 9149a37abb9e1216174cf6f93c645809400afe1e Mon Sep 17 00:00:00 2001 From: MikeMoolenaar Date: Thu, 7 Mar 2024 21:03:08 +0100 Subject: [PATCH] Fixes #10 - add padding if new seekPosition bytes are lower than initially --- .../MatroskaLib.Test/MatroskaLib.Test.csproj | 4 ++++ MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs | 13 +++++++++++++ MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs | 3 ++- .../MatroskaLib/Helpers/CustomExtensions.cs | 2 +- MatroskaLib/MatroskaLib/MatroskaWriter.cs | 10 +++++++--- MatroskaLib/MatroskaLib/Types/Seek.cs | 2 ++ .../mkv files/TestFile6_SmallSeekHead.mkv | Bin 0 -> 880 bytes 7 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 TestMkvFiles/mkv files/TestFile6_SmallSeekHead.mkv diff --git a/MatroskaLib/MatroskaLib.Test/MatroskaLib.Test.csproj b/MatroskaLib/MatroskaLib.Test/MatroskaLib.Test.csproj index fa88b03..4e9c1fd 100644 --- a/MatroskaLib/MatroskaLib.Test/MatroskaLib.Test.csproj +++ b/MatroskaLib/MatroskaLib.Test/MatroskaLib.Test.csproj @@ -49,6 +49,10 @@ mkv files\TestFile5_MkvProEdit.mkv PreserveNewest + + mkv files\TestFile6_SmallSeekHead.mkv + PreserveNewest + PreserveNewest diff --git a/MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs b/MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs index dc48fd0..5ac6e75 100644 --- a/MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs +++ b/MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs @@ -13,6 +13,9 @@ namespace MatroskaLib.Test; * Only first void with checksum elements * MkvProEdit * Only second void and may need to change length of that void + * TestFile6_SmallSeekHead.mkv + * SeekHead size of 2, which caused an exception (see github issue #10). + * Do that this is not a valid mkv file accordant to MkValidator. */ public class MatroskaLibTest { @@ -172,4 +175,14 @@ public void WriteTestFile4(string file) lsTracks[2].Should().BeEquivalentTo(new { flagDefault = false, flagForced = false, language = "jpn", type = TrackTypeEnum.audio }); MkvValidator.Validate(TestFilePath); } + + [Fact] + public void FileWithSeekHeadSizeOf2ShouldNotThrow() + { + File.Copy("mkv files/TestFile6_SmallSeekHead.mkv", TestFilePath, true); + List lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath }); + lsMkvFiles[0].tracks[0].flagDefault = false; + + MatroskaWriter.WriteMkvFile(lsMkvFiles[0]); + } } diff --git a/MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs b/MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs index 2b40271..ab3c1af 100644 --- a/MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs +++ b/MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs @@ -57,7 +57,8 @@ public static void ChangeLength(List lsBytes, int position, List lsL // Convert new length to bytes and strip bytes List lsNewBytes = ToBytes(ret); - if (lsNewBytes.Count != lsLengthBytes.Count) throw new Exception("New length doesn't fit into existing length element"); + if (lsNewBytes.Count != lsLengthBytes.Count) + throw new InvalidOperationException($"New length bytes are not the same length as the old ones. Old length: {lsLengthBytes.Count}, new length: {lsNewBytes.Count}"); // Replace old length with new length bytes lsBytes.RemoveRange(position, lsNewBytes.Count); diff --git a/MatroskaLib/MatroskaLib/Helpers/CustomExtensions.cs b/MatroskaLib/MatroskaLib/Helpers/CustomExtensions.cs index b1d9906..691c312 100644 --- a/MatroskaLib/MatroskaLib/Helpers/CustomExtensions.cs +++ b/MatroskaLib/MatroskaLib/Helpers/CustomExtensions.cs @@ -16,7 +16,7 @@ public static void LocateElement(this EbmlReader reader, ulong descriptor) } } - throw new Exception($"Cannot find descriptor 0x{descriptor:X}"); + throw new InvalidOperationException($"Cannot find descriptor 0x{descriptor:X}"); } } } diff --git a/MatroskaLib/MatroskaLib/MatroskaWriter.cs b/MatroskaLib/MatroskaLib/MatroskaWriter.cs index 4b148d7..d967a7f 100644 --- a/MatroskaLib/MatroskaLib/MatroskaWriter.cs +++ b/MatroskaLib/MatroskaLib/MatroskaWriter.cs @@ -72,10 +72,14 @@ private static void _ChangeVoidLengthAndHeaders(List seekList, int? seekHe foreach (var s in seekList.Where(s => s.seekId is MatroskaElements.Tracks or MatroskaElements.SegmentInfo)) { - int desiredLength = Convert.ToInt32(lsBytes[s.seekPositionByteNumber - 1] - 0x80); List lsNewBytes = ByteHelper.ToBytes(s.seekPosition - (ulong)offset); - if (desiredLength != lsNewBytes.Count) - throw new Exception("New seekposition doesn't fit into existing element"); + if (lsNewBytes.Count > s.elementLength) + throw new InvalidOperationException($"New seekPosition bytes are bigger than the old one. Trying to fit {lsNewBytes.Count} bytes into {s.elementLength} bytes"); + if (lsNewBytes.Count < s.elementLength) + { + // The new seekPosition is smaller than the old one, add padding + lsNewBytes.AddRange(new byte[s.elementLength - lsNewBytes.Count]); + } lsBytes.RemoveRange(s.seekPositionByteNumber, lsNewBytes.Count); lsBytes.InsertRange(s.seekPositionByteNumber, lsNewBytes); diff --git a/MatroskaLib/MatroskaLib/Types/Seek.cs b/MatroskaLib/MatroskaLib/Types/Seek.cs index 19abe44..bf3ab42 100644 --- a/MatroskaLib/MatroskaLib/Types/Seek.cs +++ b/MatroskaLib/MatroskaLib/Types/Seek.cs @@ -9,6 +9,7 @@ public class Seek public ulong seekId { get; private set; } public ulong seekPosition { get; private set; } public int seekPositionByteNumber { get; private set; } + public int elementLength { get; private set; } public Seek(EbmlReader reader) => _reader = reader; @@ -23,6 +24,7 @@ public void ApplyElement(FileStream fileStream) { seekPositionByteNumber = (int)fileStream.Position; seekPosition = _reader.ReadUInt(); + elementLength = (int)_reader.ElementSize; } } } diff --git a/TestMkvFiles/mkv files/TestFile6_SmallSeekHead.mkv b/TestMkvFiles/mkv files/TestFile6_SmallSeekHead.mkv new file mode 100644 index 0000000000000000000000000000000000000000..3912d5d6bb771ca57feae430c0bb17719b678736 GIT binary patch literal 880 zcmb1gy}x*|Q(GgW({~{L)X3uWxsk)EsUtVBq$s~QJJG2fDAd}>BoW+@&d9*Pa7RQ{ zSkQNN$>semGQCSK`tI%yUfm+48 zW_~A!>Xm)L`MIeI#TohK3YjU{mA(x&0hyTsk`(!@5_1Tm|x=UP@bkSiEn5tGkK5XRyD%W0-SuBct-;<`$;v6IlEmbt$Q( z9gPfaZI1D-j?Tu-jZ66v+nIk6yfQ}fb^Gt}*RBMZ>bg-vSl-c4c0!G_LAEQUb0{G#O4 z6u-oxqQsKSvQ)6iP#1Rx$A`E^gy@HcxLGte3c}oIbiI)kXk5?-{-^8ChVViB>ylbp z0(2tOzint*L5Wj9^SR#s7XQV8tclBkY$dn6&gA^E)FQotymYsO&P=$2Vgxjw{p<|z zbLZuf;sS;cucwDg5Ca2y0|Nt#1qTyQBzb6c{{R H978Gqu)8f6 literal 0 HcmV?d00001