aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
authortheguymadmax <171496228+theguymadmax@users.noreply.github.com>2025-12-03 14:04:23 -0500
committerBond_009 <bond.009@outlook.com>2025-12-03 14:04:23 -0500
commit5d4627858418722c85d76d27b4ba982f209505f2 (patch)
tree75e30088387a9dc9cf4e1d207e4ae9ba3530f4f8 /MediaBrowser.Controller
parent4f020a947ae7e2765a8b04bb56ffe11caf24aeb8 (diff)
Backport pull request #15568 from jellyfin/release-10.11.z
Fix ResolveLinkTarget crashing on exFAT drives Original-merge: fbb9a0b2c7c5afbc56be76a4eb11a1045f0ab0f0 Merged-by: crobibero <cody@robibe.ro> Backported-by: Bond_009 <bond.009@outlook.com>
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/IO/FileSystemHelper.cs42
1 files changed, 34 insertions, 8 deletions
diff --git a/MediaBrowser.Controller/IO/FileSystemHelper.cs b/MediaBrowser.Controller/IO/FileSystemHelper.cs
index 3e390ca42..44b7fadf5 100644
--- a/MediaBrowser.Controller/IO/FileSystemHelper.cs
+++ b/MediaBrowser.Controller/IO/FileSystemHelper.cs
@@ -64,6 +64,29 @@ public static class FileSystemHelper
}
/// <summary>
+ /// Resolves a single link hop for the specified path.
+ /// </summary>
+ /// <remarks>
+ /// Returns <c>null</c> if the path is not a symbolic link or the filesystem does not support link resolution (e.g., exFAT).
+ /// </remarks>
+ /// <param name="path">The file path to resolve.</param>
+ /// <returns>
+ /// A <see cref="FileInfo"/> representing the next link target if the path is a link; otherwise, <c>null</c>.
+ /// </returns>
+ private static FileInfo? Resolve(string path)
+ {
+ try
+ {
+ return File.ResolveLinkTarget(path, returnFinalTarget: false) as FileInfo;
+ }
+ catch (IOException)
+ {
+ // Filesystem doesn't support links (e.g., exFAT).
+ return null;
+ }
+ }
+
+ /// <summary>
/// Gets the target of the specified file link.
/// </summary>
/// <remarks>
@@ -84,23 +107,26 @@ public static class FileSystemHelper
if (!returnFinalTarget)
{
- return File.ResolveLinkTarget(linkPath, returnFinalTarget: false) as FileInfo;
- }
-
- if (File.ResolveLinkTarget(linkPath, returnFinalTarget: false) is not FileInfo targetInfo)
- {
- return null;
+ return Resolve(linkPath);
}
- if (!targetInfo.Exists)
+ var targetInfo = Resolve(linkPath);
+ if (targetInfo is null || !targetInfo.Exists)
{
return targetInfo;
}
var currentPath = targetInfo.FullName;
var visited = new HashSet<string>(StringComparer.Ordinal) { linkPath, currentPath };
- while (File.ResolveLinkTarget(currentPath, returnFinalTarget: false) is FileInfo linkInfo)
+
+ while (true)
{
+ var linkInfo = Resolve(currentPath);
+ if (linkInfo is null)
+ {
+ break;
+ }
+
var targetPath = linkInfo.FullName;
// If an infinite loop is detected, return the file info for the