diff options
| author | Cody Robibero <cody@robibe.ro> | 2026-08-30 17:52:39 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-30 17:52:39 -0400 |
| commit | 7d6633ad1e9b4b69be87b2ac601fcadbacc37376 (patch) | |
| tree | 6226761d735d99cd3114eb781177cd2435d0a9bf | |
| parent | 420d44f638c44b942b43303c3165c2e8795b9020 (diff) | |
| parent | 11adad0e67f9487536ed8e727955645c4dee4244 (diff) | |
Fix formatting and test
| -rw-r--r-- | MediaBrowser.Controller/IO/FileSystemHelper.cs | 11 | ||||
| -rw-r--r-- | src/Jellyfin.Drawing.Skia/SvgSecurityValidator.cs | 58 | ||||
| -rw-r--r-- | tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs | 20 |
3 files changed, 56 insertions, 33 deletions
diff --git a/MediaBrowser.Controller/IO/FileSystemHelper.cs b/MediaBrowser.Controller/IO/FileSystemHelper.cs index f636258191..b2d2273cbe 100644 --- a/MediaBrowser.Controller/IO/FileSystemHelper.cs +++ b/MediaBrowser.Controller/IO/FileSystemHelper.cs @@ -193,8 +193,13 @@ public static class FileSystemHelper var fullParentPath = Path.TrimEndingDirectorySeparator(Path.GetFullPath(parentPath)); // Catches the remaining relative names, "." and "..", which are valid single segments. - return string.Equals(Path.GetDirectoryName(fullPath), fullParentPath, StringComparison.Ordinal) - ? fullPath - : null; + if (!string.Equals(Path.GetDirectoryName(fullPath), fullParentPath, StringComparison.Ordinal)) + { + return null; + } + + // Windows strips trailing dots and spaces, so a name like "..." resolves to the parent directory itself + // and a name like "Movies." to a different child. Reject anything normalization did not leave intact. + return string.Equals(Path.GetFileName(fullPath), name, StringComparison.Ordinal) ? fullPath : null; } } diff --git a/src/Jellyfin.Drawing.Skia/SvgSecurityValidator.cs b/src/Jellyfin.Drawing.Skia/SvgSecurityValidator.cs index f8a1d7d443..65f35643b2 100644 --- a/src/Jellyfin.Drawing.Skia/SvgSecurityValidator.cs +++ b/src/Jellyfin.Drawing.Skia/SvgSecurityValidator.cs @@ -83,48 +83,48 @@ internal static class SvgSecurityValidator switch (reader.NodeType) { case XmlNodeType.DocumentType: - { - var subset = reader.Value; - if (!string.IsNullOrEmpty(subset) - && (subset.Contains("SYSTEM", StringComparison.OrdinalIgnoreCase) - || subset.Contains("PUBLIC", StringComparison.OrdinalIgnoreCase))) { - return "The document declares an external DTD entity"; - } + var subset = reader.Value; + if (!string.IsNullOrEmpty(subset) + && (subset.Contains("SYSTEM", StringComparison.OrdinalIgnoreCase) + || subset.Contains("PUBLIC", StringComparison.OrdinalIgnoreCase))) + { + return "The document declares an external DTD entity"; + } - break; - } + break; + } case XmlNodeType.Element when reader.HasAttributes: - { - for (var i = 0; i < reader.AttributeCount; i++) { - reader.MoveToAttribute(i); - var isHref = reader.LocalName.Equals("href", StringComparison.OrdinalIgnoreCase); - var reason = isHref - ? ValidateReference(reader.Value, depth, "href") - : ValidateCss(reader.Value, depth); - if (reason is not null) + for (var i = 0; i < reader.AttributeCount; i++) { - return reason; + reader.MoveToAttribute(i); + var isHref = reader.LocalName.Equals("href", StringComparison.OrdinalIgnoreCase); + var reason = isHref + ? ValidateReference(reader.Value, depth, "href") + : ValidateCss(reader.Value, depth); + if (reason is not null) + { + return reason; + } } - } - reader.MoveToElement(); - break; - } + reader.MoveToElement(); + break; + } case XmlNodeType.Text: case XmlNodeType.CDATA: - { - var reason = ValidateCss(reader.Value, depth); - if (reason is not null) { - return reason; - } + var reason = ValidateCss(reader.Value, depth); + if (reason is not null) + { + return reason; + } - break; - } + break; + } } } diff --git a/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs b/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs index 4c7addd164..b4ec2f1903 100644 --- a/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs +++ b/tests/Jellyfin.Controller.Tests/IO/FileSystemHelperTests.cs @@ -13,7 +13,6 @@ public class FileSystemHelperTests [InlineData("Movies")] [InlineData("My Movies")] [InlineData("..2")] - [InlineData("...")] [InlineData("a.b")] public void GetChildPath_ValidName_ReturnsPathInsideParent(string name) { @@ -50,6 +49,25 @@ public class FileSystemHelperTests Assert.True(path is null || string.Equals(Path.GetDirectoryName(path), _parentPath, StringComparison.Ordinal)); } + [Theory] + [InlineData("...")] + [InlineData("Movies.")] + [InlineData("Movies ")] + public void GetChildPath_TrailingDotOrSpace_RejectedOnWindows(string name) + { + var path = FileSystemHelper.GetChildPath(_parentPath, name); + + if (OperatingSystem.IsWindows()) + { + // Windows trims trailing dots and spaces, so the name would resolve to the parent or to a different child. + Assert.Null(path); + } + else + { + Assert.Equal(Path.Combine(_parentPath, name), path); + } + } + [Fact] public void GetChildPath_ParentWithTrailingSeparator_ReturnsPathInsideParent() { |
