aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-08-25 09:28:45 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-08-25 09:28:45 +0200
commit0c560b22ce73323329645b836c9910abc257ce4e (patch)
treeca907f705a94450c39cece7e0ecc5ece5d2090ca /tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs
parentd6bcad3b59aa8f8069cdcba075b4878c845b780b (diff)
Secure library paths
Diffstat (limited to 'tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs')
-rw-r--r--tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs60
1 files changed, 60 insertions, 0 deletions
diff --git a/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs b/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs
new file mode 100644
index 0000000000..4c7addd164
--- /dev/null
+++ b/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs
@@ -0,0 +1,60 @@
+using System;
+using System.IO;
+using MediaBrowser.Controller.IO;
+using Xunit;
+
+namespace Jellyfin.Controller.Tests.IO;
+
+public class FileSystemHelperTests
+{
+ private static readonly string _parentPath = Path.Combine(Path.GetTempPath(), "jellyfin-test", "root", "default");
+
+ [Theory]
+ [InlineData("Movies")]
+ [InlineData("My Movies")]
+ [InlineData("..2")]
+ [InlineData("...")]
+ [InlineData("a.b")]
+ public void GetChildPath_ValidName_ReturnsPathInsideParent(string name)
+ {
+ var path = FileSystemHelper.GetChildPath(_parentPath, name);
+
+ Assert.Equal(Path.Combine(_parentPath, name), path);
+ }
+
+ [Theory]
+ [InlineData("")]
+ [InlineData(" ")]
+ [InlineData(".")]
+ [InlineData("..")]
+ [InlineData("../..")]
+ [InlineData("../../etc")]
+ [InlineData("Movies/../..")]
+ [InlineData("/var/lib/jellyfin/data")]
+ [InlineData("sub/folder")]
+ [InlineData("with\0null")]
+ public void GetChildPath_EscapingName_ReturnsNull(string name)
+ {
+ Assert.Null(FileSystemHelper.GetChildPath(_parentPath, name));
+ }
+
+ [Theory]
+ [InlineData("..\\..")]
+ [InlineData("sub\\folder")]
+ [InlineData("C:\\Windows")]
+ public void GetChildPath_WindowsSeparator_DoesNotEscapeParent(string name)
+ {
+ var path = FileSystemHelper.GetChildPath(_parentPath, name);
+
+ // On Windows these are rejected outright, on other platforms a backslash is a legal file name character.
+ Assert.True(path is null || string.Equals(Path.GetDirectoryName(path), _parentPath, StringComparison.Ordinal));
+ }
+
+ [Fact]
+ public void GetChildPath_ParentWithTrailingSeparator_ReturnsPathInsideParent()
+ {
+ var path = FileSystemHelper.GetChildPath(_parentPath + Path.DirectorySeparatorChar, "Movies");
+
+ Assert.Equal(Path.Combine(_parentPath, "Movies"), path);
+ }
+}