diff --git a/Jellyfin.sln b/Jellyfin.sln
index 436df9a58..02ae2a504 100644
--- a/Jellyfin.sln
+++ b/Jellyfin.sln
@@ -93,6 +93,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Keyf
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Hls", "src\Jellyfin.MediaEncoding.Hls\Jellyfin.MediaEncoding.Hls.csproj", "{DA9FD356-4894-4830-B208-D6BCE3E65B11}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Hls.Tests", "tests\Jellyfin.MediaEncoding.Hls.Tests\Jellyfin.MediaEncoding.Hls.Tests.csproj", "{FE47334C-EFDE-4519-BD50-F24430FF360B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -251,6 +253,10 @@ Global
{DA9FD356-4894-4830-B208-D6BCE3E65B11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA9FD356-4894-4830-B208-D6BCE3E65B11}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{DA9FD356-4894-4830-B208-D6BCE3E65B11}.Release|Any CPU.Build.0 = Debug|Any CPU
+ {FE47334C-EFDE-4519-BD50-F24430FF360B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE47334C-EFDE-4519-BD50-F24430FF360B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE47334C-EFDE-4519-BD50-F24430FF360B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE47334C-EFDE-4519-BD50-F24430FF360B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -273,6 +279,7 @@ Global
{332A5C7A-F907-47CA-910E-BE6F7371B9E0} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
{06535CA1-4097-4360-85EB-5FB875D53239} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
{DA9FD356-4894-4830-B208-D6BCE3E65B11} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
+ {FE47334C-EFDE-4519-BD50-F24430FF360B} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE}
diff --git a/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj b/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
index 6e58c4179..c7adbb621 100644
--- a/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
+++ b/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
@@ -2,14 +2,9 @@
net5.0
- false
true
-
-
-
-
@@ -22,9 +17,15 @@
-
+
+
+
+ <_Parameter1>Jellyfin.MediaEncoding.Hls.Tests
+
+
+
diff --git a/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs b/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs
index 7abb3c331..9cb52e678 100644
--- a/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs
+++ b/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs
@@ -176,12 +176,18 @@ namespace Jellyfin.MediaEncoding.Hls.Playlist
internal static bool IsExtractionAllowedForFile(ReadOnlySpan filePath, string[] allowedExtensions)
{
+ var extension = Path.GetExtension(filePath);
+ if (extension.IsEmpty)
+ {
+ return false;
+ }
+
// Remove the leading dot
- var extension = Path.GetExtension(filePath)[1..];
+ var extensionWithoutDot = extension[1..];
for (var i = 0; i < allowedExtensions.Length; i++)
{
var allowedExtension = allowedExtensions[i];
- if (extension.Equals(allowedExtension, StringComparison.OrdinalIgnoreCase))
+ if (extensionWithoutDot.Equals(allowedExtension, StringComparison.OrdinalIgnoreCase))
{
return true;
}
diff --git a/tests/Jellyfin.MediaEncoding.Hls.Tests/Jellyfin.MediaEncoding.Hls.Tests.csproj b/tests/Jellyfin.MediaEncoding.Hls.Tests/Jellyfin.MediaEncoding.Hls.Tests.csproj
new file mode 100644
index 000000000..1b53d670f
--- /dev/null
+++ b/tests/Jellyfin.MediaEncoding.Hls.Tests/Jellyfin.MediaEncoding.Hls.Tests.csproj
@@ -0,0 +1,32 @@
+
+
+
+ net5.0
+ false
+ ../jellyfin-tests.ruleset
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Jellyfin.MediaEncoding.Hls.Tests/Playlist/DynamicHlsPlaylistGeneratorTests.cs b/tests/Jellyfin.MediaEncoding.Hls.Tests/Playlist/DynamicHlsPlaylistGeneratorTests.cs
new file mode 100644
index 000000000..c55b7e304
--- /dev/null
+++ b/tests/Jellyfin.MediaEncoding.Hls.Tests/Playlist/DynamicHlsPlaylistGeneratorTests.cs
@@ -0,0 +1,25 @@
+using Jellyfin.MediaEncoding.Hls.Playlist;
+using Xunit;
+
+namespace Jellyfin.MediaEncoding.Hls.Tests.Playlist
+{
+ public class DynamicHlsPlaylistGeneratorTests
+ {
+ [Theory]
+ [InlineData("testfile.mkv", new string[0], false)]
+ [InlineData("testfile.flv", new[] { "mp4", "mkv", "ts" }, false)]
+ [InlineData("testfile.flv", new[] { "mp4", "mkv", "ts", "flv" }, true)]
+ [InlineData("/some/arbitrarily/long/path/testfile.mkv", new[] { "mkv" }, true)]
+ public void IsExtractionAllowedForFile_Valid_Success(string filePath, string[] allowedExtensions, bool isAllowed)
+ {
+ Assert.Equal(isAllowed, DynamicHlsPlaylistGenerator.IsExtractionAllowedForFile(filePath, allowedExtensions));
+ }
+
+ [Theory]
+ [InlineData("testfile", new[] { "mp4" })]
+ public void IsExtractionAllowedForFile_Invalid_ReturnsFalse(string filePath, string[] allowedExtensions)
+ {
+ Assert.False(DynamicHlsPlaylistGenerator.IsExtractionAllowedForFile(filePath, allowedExtensions));
+ }
+ }
+}