using System; using System.Collections.Generic; using Paca.Core; using Xunit; namespace Paca.Tests.Core; public class MediaMuxerAndMetadataExtremeRedTests { private const string SampleIn1 = "C:\\Media\\video.mp4"; private const string SampleAudio = "C:\\Media\\audio.m4a"; private const string SampleOut = "C:\\Media\\output.mp4"; // ========================================== // 1. MediaMetadataTagWriter // ========================================== [Fact] public void MediaMetadataTagWriter_BuildFfmpegArgs_NullTag_ThrowsArgumentNullException() { Assert.Throws(() => MediaMetadataTagWriter.BuildFfmpegArgs(null!, SampleIn1, SampleOut)); } [Theory] [InlineData(null, SampleOut)] [InlineData(SampleIn1, null)] [InlineData("", SampleOut)] [InlineData(SampleIn1, " ")] public void MediaMetadataTagWriter_BuildFfmpegArgs_NullOrWhitespacePaths_ThrowsArgumentException(string? inPath, string? outPath) { var tag = new MediaMetadataTag { Title = "Song" }; Assert.Throws(() => MediaMetadataTagWriter.BuildFfmpegArgs(tag, inPath!, outPath!)); } [Fact] public void MediaMetadataTagWriter_BuildFfmpegArgs_SameInputAndOutput_ThrowsInvalidOperationException() { var tag = new MediaMetadataTag { Title = "Song" }; Assert.Throws(() => MediaMetadataTagWriter.BuildFfmpegArgs(tag, SampleIn1, SampleIn1)); } [Fact] public void MediaMetadataTagWriter_BuildFfmpegArgs_PathsWithQuotes_EscapedOrStripped() { var tag = new MediaMetadataTag { Title = "Song" }; string maliciousIn = "C:\\Media\\in\"put.mp4"; string maliciousOut = "C:\\Media\\out\"put.mp4"; var cmd = MediaMetadataTagWriter.BuildFfmpegArgs(tag, maliciousIn, maliciousOut); Assert.NotNull(cmd); Assert.DoesNotContain("in\"put", cmd); Assert.DoesNotContain("out\"put", cmd); } // ========================================== // 2. MultiTrackMediaMuxer // ========================================== [Fact] public void MultiTrackMediaMuxer_BuildMuxCommandLine_NullJob_ThrowsArgumentNullException() { Assert.Throws(() => MultiTrackMediaMuxer.BuildMuxCommandLine(null!)); } [Theory] [InlineData(null)] [InlineData("")] [InlineData(" ")] public void MultiTrackMediaMuxer_BuildMuxCommandLine_NullOrWhitespaceOutputPath_ThrowsArgumentException(string? badOut) { var job = new MuxJobSpecification { VideoTrack = new TrackSpec(SampleIn1), OutputPath = badOut! }; Assert.Throws(() => MultiTrackMediaMuxer.BuildMuxCommandLine(job)); } [Fact] public void MultiTrackMediaMuxer_BuildMuxCommandLine_NoTracks_ThrowsInvalidOperationException() { var job = new MuxJobSpecification { OutputPath = SampleOut }; Assert.Throws(() => MultiTrackMediaMuxer.BuildMuxCommandLine(job)); } [Fact] public void MultiTrackMediaMuxer_BuildMuxCommandLine_OutputPathMatchesAnyInput_ThrowsInvalidOperationException() { var job = new MuxJobSpecification { VideoTrack = new TrackSpec(SampleIn1), AudioTracks = new List { new(SampleAudio) }, OutputPath = SampleAudio // Overwriting audio source! }; Assert.Throws(() => MultiTrackMediaMuxer.BuildMuxCommandLine(job)); } [Fact] public void MultiTrackMediaMuxer_BuildMuxCommandLine_TrackTitleWithQuotes_EscapedSafely() { var job = new MuxJobSpecification { VideoTrack = new TrackSpec(SampleIn1), AudioTracks = new List { new(SampleAudio, Title: "Director's \"Commentary\"") }, OutputPath = SampleOut }; var cmd = MultiTrackMediaMuxer.BuildMuxCommandLine(job); Assert.NotNull(cmd); Assert.DoesNotContain("title=\"Director's \"Commentary\"\"", cmd); } // ========================================== // 3. VideoTonemapEnhancer // ========================================== [Theory] [InlineData(null, SampleOut)] [InlineData(SampleIn1, null)] public void VideoTonemapEnhancer_BuildFfmpegArgs_NullOrWhitespacePaths_ThrowsArgumentException(string? inPath, string? outPath) { Assert.Throws(() => VideoTonemapEnhancer.BuildFfmpegArgs(inPath!, outPath!, TonemapAlgorithm.Hable, ColorGradePreset.None)); } [Fact] public void VideoTonemapEnhancer_BuildFfmpegArgs_SameInputAndOutput_ThrowsInvalidOperationException() { Assert.Throws(() => VideoTonemapEnhancer.BuildFfmpegArgs(SampleIn1, SampleIn1, TonemapAlgorithm.Hable, ColorGradePreset.None)); } [Fact] public void VideoTonemapEnhancer_BuildFfmpegArgs_PathsWithQuotes_EscapedOrStripped() { string maliciousIn = "C:\\Media\\in\"put.mp4"; string maliciousOut = "C:\\Media\\out\"put.mp4"; var cmd = VideoTonemapEnhancer.BuildFfmpegArgs(maliciousIn, maliciousOut, TonemapAlgorithm.Hable, ColorGradePreset.None); Assert.NotNull(cmd); Assert.DoesNotContain("in\"put", cmd); Assert.DoesNotContain("out\"put", cmd); } [Fact] public void VideoTonemapEnhancer_BuildFfmpegArgs_InvalidEncoderOrCrf_ClampedSafely() { var cmd = VideoTonemapEnhancer.BuildFfmpegArgs( SampleIn1, SampleOut, TonemapAlgorithm.Hable, ColorGradePreset.None, crf: 999, videoEncoder: "libx264; echo pwned"); Assert.NotNull(cmd); Assert.Contains("-crf 51", cmd); Assert.DoesNotContain(";", cmd); } }