From 6f2e42c20c43fdafe66e4403979c5b3e50a90360 Mon Sep 17 00:00:00 2001 From: Gabriel Luci Date: Mon, 4 May 2026 23:46:00 -0400 Subject: Fix use of thread-unsafe List.Sort() --- MediaBrowser.Controller/Providers/DirectoryService.cs | 9 ++------- MediaBrowser.Controller/Providers/IDirectoryService.cs | 2 +- MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs | 8 ++++---- .../MediaInfo/MediaInfoResolverTests.cs | 18 +++++++++--------- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index 5b5af75a47..6060d051a5 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Controller.Providers public IReadOnlyList GetFilePaths(string path) => GetFilePaths(path, false); - public IReadOnlyList GetFilePaths(string path, bool clearCache, bool sort = false) + public IReadOnlyList GetFilePaths(string path, bool clearCache) { if (clearCache) { @@ -118,7 +118,7 @@ namespace MediaBrowser.Controller.Providers { try { - return fileSystem.GetFilePaths(p).ToList(); + return fileSystem.GetFilePaths(p).OrderBy(x => x).ToList(); } catch (DirectoryNotFoundException) { @@ -127,11 +127,6 @@ namespace MediaBrowser.Controller.Providers }, _fileSystem); - if (sort) - { - filePaths.Sort(); - } - return filePaths; } diff --git a/MediaBrowser.Controller/Providers/IDirectoryService.cs b/MediaBrowser.Controller/Providers/IDirectoryService.cs index 1babf73af8..8a3fa33da3 100644 --- a/MediaBrowser.Controller/Providers/IDirectoryService.cs +++ b/MediaBrowser.Controller/Providers/IDirectoryService.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Providers IReadOnlyList GetFilePaths(string path); - IReadOnlyList GetFilePaths(string path, bool clearCache, bool sort = false); + IReadOnlyList GetFilePaths(string path, bool clearCache); bool IsAccessible(string path); } diff --git a/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs b/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs index 0716cdfa01..6f9d5f19da 100644 --- a/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs +++ b/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs @@ -218,12 +218,12 @@ namespace MediaBrowser.Providers.MediaInfo return Array.Empty(); } - var files = directoryService.GetFilePaths(folder, clearCache, true).ToList(); + var files = directoryService.GetFilePaths(folder, clearCache).ToList(); files.Remove(video.Path); var internalMetadataPath = video.GetInternalMetadataPath(); if (_fileSystem.DirectoryExists(internalMetadataPath)) { - files.AddRange(directoryService.GetFilePaths(internalMetadataPath, clearCache, true)); + files.AddRange(directoryService.GetFilePaths(internalMetadataPath, clearCache)); } if (files.Count == 0) @@ -270,12 +270,12 @@ namespace MediaBrowser.Providers.MediaInfo } string folder = audio.ContainingFolderPath; - var files = directoryService.GetFilePaths(folder, clearCache, true).ToList(); + var files = directoryService.GetFilePaths(folder, clearCache).ToList(); files.Remove(audio.Path); var internalMetadataPath = audio.GetInternalMetadataPath(); if (_fileSystem.DirectoryExists(internalMetadataPath)) { - files.AddRange(directoryService.GetFilePaths(internalMetadataPath, clearCache, true)); + files.AddRange(directoryService.GetFilePaths(internalMetadataPath, clearCache)); } if (files.Count == 0) diff --git a/tests/Jellyfin.Providers.Tests/MediaInfo/MediaInfoResolverTests.cs b/tests/Jellyfin.Providers.Tests/MediaInfo/MediaInfoResolverTests.cs index 222e624aa2..876f18741f 100644 --- a/tests/Jellyfin.Providers.Tests/MediaInfo/MediaInfoResolverTests.cs +++ b/tests/Jellyfin.Providers.Tests/MediaInfo/MediaInfoResolverTests.cs @@ -123,13 +123,13 @@ public class MediaInfoResolverTests var directoryService = new Mock(MockBehavior.Strict); // any path other than test target exists and provides an empty listing - directoryService.Setup(ds => ds.GetFilePaths(It.IsAny(), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsAny(), It.IsAny())) .Returns(Array.Empty()); _subtitleResolver.GetExternalFiles(video.Object, directoryService.Object, false); directoryService.Verify( - ds => ds.GetFilePaths(It.IsRegex(pathNotFoundRegex), It.IsAny(), It.IsAny()), + ds => ds.GetFilePaths(It.IsRegex(pathNotFoundRegex), It.IsAny()), Times.Never); } @@ -196,7 +196,7 @@ public class MediaInfoResolverTests }; var directoryService = new Mock(MockBehavior.Strict); - directoryService.Setup(ds => ds.GetFilePaths(It.IsAny(), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsAny(), It.IsAny())) .Returns(Array.Empty()); var mediaEncoder = Mock.Of(MockBehavior.Strict); @@ -341,9 +341,9 @@ public class MediaInfoResolverTests } var directoryService = new Mock(MockBehavior.Strict); - directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(VideoDirectoryRegex), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(VideoDirectoryRegex), It.IsAny())) .Returns(files); - directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(MetadataDirectoryRegex), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(MetadataDirectoryRegex), It.IsAny())) .Returns(Array.Empty()); List GenerateMediaStreams() @@ -413,16 +413,16 @@ public class MediaInfoResolverTests var directoryService = new Mock(MockBehavior.Strict); if (useMetadataDirectory) { - directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(VideoDirectoryRegex), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(VideoDirectoryRegex), It.IsAny())) .Returns(Array.Empty()); - directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(MetadataDirectoryRegex), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(MetadataDirectoryRegex), It.IsAny())) .Returns(new[] { MetadataDirectoryPath + "/" + file }); } else { - directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(VideoDirectoryRegex), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(VideoDirectoryRegex), It.IsAny())) .Returns(new[] { VideoDirectoryPath + "/" + file }); - directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(MetadataDirectoryRegex), It.IsAny(), It.IsAny())) + directoryService.Setup(ds => ds.GetFilePaths(It.IsRegex(MetadataDirectoryRegex), It.IsAny())) .Returns(Array.Empty()); } -- cgit v1.2.3