From 891b9f7a997ce5e5892c1b0f166a921ff07abf68 Mon Sep 17 00:00:00 2001 From: AmbulantRex <21176662+AmbulantRex@users.noreply.github.com> Date: Thu, 30 Mar 2023 08:59:21 -0600 Subject: Add DLL whitelist support for plugins --- .../Library/PathExtensions.cs | 99 +++++++++++++++++----- 1 file changed, 80 insertions(+), 19 deletions(-) (limited to 'Emby.Server.Implementations/Library/PathExtensions.cs') diff --git a/Emby.Server.Implementations/Library/PathExtensions.cs b/Emby.Server.Implementations/Library/PathExtensions.cs index 64e7d5446..7e0d0b78d 100644 --- a/Emby.Server.Implementations/Library/PathExtensions.cs +++ b/Emby.Server.Implementations/Library/PathExtensions.cs @@ -1,6 +1,9 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; using MediaBrowser.Common.Providers; +using Nikse.SubtitleEdit.Core.Common; namespace Emby.Server.Implementations.Library { @@ -86,24 +89,8 @@ namespace Emby.Server.Implementations.Library return false; } - char oldDirectorySeparatorChar; - char newDirectorySeparatorChar; - // True normalization is still not possible https://github.com/dotnet/runtime/issues/2162 - // The reasoning behind this is that a forward slash likely means it's a Linux path and - // so the whole path should be normalized to use / and vice versa for Windows (although Windows doesn't care much). - if (newSubPath.Contains('/', StringComparison.Ordinal)) - { - oldDirectorySeparatorChar = '\\'; - newDirectorySeparatorChar = '/'; - } - else - { - oldDirectorySeparatorChar = '/'; - newDirectorySeparatorChar = '\\'; - } - - path = path.Replace(oldDirectorySeparatorChar, newDirectorySeparatorChar); - subPath = subPath.Replace(oldDirectorySeparatorChar, newDirectorySeparatorChar); + subPath = subPath.NormalizePath(out var newDirectorySeparatorChar)!; + path = path.NormalizePath(newDirectorySeparatorChar)!; // We have to ensure that the sub path ends with a directory separator otherwise we'll get weird results // when the sub path matches a similar but in-complete subpath @@ -120,12 +107,86 @@ namespace Emby.Server.Implementations.Library return false; } - var newSubPathTrimmed = newSubPath.AsSpan().TrimEnd(newDirectorySeparatorChar); + var newSubPathTrimmed = newSubPath.AsSpan().TrimEnd((char)newDirectorySeparatorChar!); // Ensure that the path with the old subpath removed starts with a leading dir separator int idx = oldSubPathEndsWithSeparator ? subPath.Length - 1 : subPath.Length; newPath = string.Concat(newSubPathTrimmed, path.AsSpan(idx)); return true; } + + /// + /// Retrieves the full resolved path and normalizes path separators to the . + /// + /// The path to canonicalize. + /// The fully expanded, normalized path. + public static string Canonicalize(this string path) + { + return Path.GetFullPath(path).NormalizePath()!; + } + + /// + /// Normalizes the path's directory separator character to the currently defined . + /// + /// The path to normalize. + /// The normalized path string or if the input path is null or empty. + public static string? NormalizePath(this string? path) + { + return path.NormalizePath(Path.DirectorySeparatorChar); + } + + /// + /// Normalizes the path's directory separator character. + /// + /// The path to normalize. + /// The separator character the path now uses or . + /// The normalized path string or if the input path is null or empty. + public static string? NormalizePath(this string? path, out char separator) + { + if (string.IsNullOrEmpty(path)) + { + separator = default; + return path; + } + + var newSeparator = '\\'; + + // True normalization is still not possible https://github.com/dotnet/runtime/issues/2162 + // The reasoning behind this is that a forward slash likely means it's a Linux path and + // so the whole path should be normalized to use / and vice versa for Windows (although Windows doesn't care much). + if (path.Contains('/', StringComparison.Ordinal)) + { + newSeparator = '/'; + } + + separator = newSeparator; + + return path?.NormalizePath(newSeparator); + } + + /// + /// Normalizes the path's directory separator character to the specified character. + /// + /// The path to normalize. + /// The replacement directory separator character. Must be a valid directory separator. + /// The normalized path. + /// Thrown if the new separator character is not a directory separator. + public static string? NormalizePath(this string? path, char newSeparator) + { + const char Bs = '\\'; + const char Fs = '/'; + + if (!(newSeparator == Bs || newSeparator == Fs)) + { + throw new ArgumentException("The character must be a directory separator."); + } + + if (string.IsNullOrEmpty(path)) + { + return path; + } + + return newSeparator == Bs ? path?.Replace(Fs, newSeparator) : path?.Replace(Bs, newSeparator); + } } } -- cgit v1.2.3