Skip to content

Commit

Permalink
Fixes #10 - add padding if new seekPosition bytes are lower than init…
Browse files Browse the repository at this point in the history
…ially
  • Loading branch information
MikeMoolenaar committed Mar 7, 2024
1 parent e323805 commit 9149a37
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 5 deletions.
4 changes: 4 additions & 0 deletions MatroskaLib/MatroskaLib.Test/MatroskaLib.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
<Link>mkv files\TestFile5_MkvProEdit.mkv</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\TestMkvFiles\mkv files\TestFile6_SmallSeekHead.mkv">
<Link>mkv files\TestFile6_SmallSeekHead.mkv</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="mkvalidator.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down
13 changes: 13 additions & 0 deletions MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
lsMkvFiles[0].tracks[0].flagDefault = false;

MatroskaWriter.WriteMkvFile(lsMkvFiles[0]);
}
}
3 changes: 2 additions & 1 deletion MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public static void ChangeLength(List<byte> lsBytes, int position, List<byte> lsL

// Convert new length to bytes and strip bytes
List<byte> 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);
Expand Down
2 changes: 1 addition & 1 deletion MatroskaLib/MatroskaLib/Helpers/CustomExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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}");
}
}
}
10 changes: 7 additions & 3 deletions MatroskaLib/MatroskaLib/MatroskaWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ private static void _ChangeVoidLengthAndHeaders(List<Seek> 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<byte> 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);
Expand Down
2 changes: 2 additions & 0 deletions MatroskaLib/MatroskaLib/Types/Seek.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,6 +24,7 @@ public void ApplyElement(FileStream fileStream)
{
seekPositionByteNumber = (int)fileStream.Position;
seekPosition = _reader.ReadUInt();
elementLength = (int)_reader.ElementSize;
}
}
}
Binary file added TestMkvFiles/mkv files/TestFile6_SmallSeekHead.mkv
Binary file not shown.

0 comments on commit 9149a37

Please sign in to comment.