diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 10d5ea906e..48584ae0cb 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -432,7 +432,7 @@ namespace Emby.Server.Implementations.Plugins ImagePath = imagePath }; - if (!ReconcileManifest(manifest, path)) + if (!await ReconcileManifest(manifest, path)) { // An error occurred during reconciliation and saving could be undesirable. return false; @@ -448,7 +448,7 @@ namespace Emby.Server.Implementations.Plugins /// The to reconcile against. /// The plugin path. /// The reconciled . - private bool ReconcileManifest(PluginManifest manifest, string path) + private async Task ReconcileManifest(PluginManifest manifest, string path) { try { @@ -459,8 +459,9 @@ namespace Emby.Server.Implementations.Plugins return true; } - var data = File.ReadAllBytes(metafile); - var localManifest = JsonSerializer.Deserialize(data, _jsonOptions) ?? new PluginManifest(); + using var metaStream = File.OpenRead(metafile); + var localManifest = await JsonSerializer.DeserializeAsync(metaStream, _jsonOptions); + localManifest ??= new PluginManifest(); if (!Equals(localManifest.Id, manifest.Id)) { @@ -483,7 +484,7 @@ namespace Emby.Server.Implementations.Plugins manifest.Overview = string.IsNullOrEmpty(localManifest.Overview) ? manifest.Overview : localManifest.Overview; manifest.Owner = string.IsNullOrEmpty(localManifest.Owner) ? manifest.Owner : localManifest.Owner; manifest.TargetAbi = string.IsNullOrEmpty(localManifest.TargetAbi) ? manifest.TargetAbi : localManifest.TargetAbi; - manifest.Timestamp = localManifest.Timestamp.IsNullOrDefault() ? manifest.Timestamp : localManifest.Timestamp; + manifest.Timestamp = localManifest.Timestamp.Equals(default) ? manifest.Timestamp : localManifest.Timestamp; manifest.ImagePath = string.IsNullOrEmpty(localManifest.ImagePath) ? manifest.ImagePath : localManifest.ImagePath; manifest.Assemblies = localManifest.Assemblies; @@ -842,7 +843,7 @@ namespace Emby.Server.Implementations.Plugins var canonicalized = Path.Combine(plugin.Path, path).Canonicalize(); // Ensure we stay in the plugin directory. - if (!canonicalized.StartsWith(plugin.Path.NormalizePath()!, StringComparison.Ordinal)) + if (!canonicalized.StartsWith(plugin.Path.NormalizePath(), StringComparison.Ordinal)) { _logger.LogError("Assembly path {Path} is not inside the plugin directory.", path); return false; diff --git a/src/Jellyfin.Extensions/TypeExtensions.cs b/src/Jellyfin.Extensions/TypeExtensions.cs deleted file mode 100644 index 5b1111d594..0000000000 --- a/src/Jellyfin.Extensions/TypeExtensions.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Globalization; - -namespace Jellyfin.Extensions; - -/// -/// Provides extensions methods for . -/// -public static class TypeExtensions -{ - /// - /// Checks if the supplied value is the default or null value for that type. - /// - /// The type of the value to compare. - /// The type. - /// The value to check. - /// if the value is the default for the type. Otherwise, . - public static bool IsNullOrDefault(this Type type, T value) - { - if (value is null) - { - return true; - } - - object? tmp = value; - object? defaultValue = type.IsValueType ? Activator.CreateInstance(type) : null; - if (type.IsAssignableTo(typeof(IConvertible))) - { - tmp = Convert.ChangeType(value, type, CultureInfo.InvariantCulture); - } - - return Equals(tmp, defaultValue); - } - - /// - /// Checks if the object is currently a default or null value. Boxed types will be unboxed prior to comparison. - /// - /// The object to check. - /// if the value is the default for the type. Otherwise, . - public static bool IsNullOrDefault(this object? obj) - { - // Unbox the type and check. - return obj?.GetType().IsNullOrDefault(obj) ?? true; - } -} diff --git a/tests/Jellyfin.Extensions.Tests/TypeExtensionsTests.cs b/tests/Jellyfin.Extensions.Tests/TypeExtensionsTests.cs deleted file mode 100644 index 747913fa1a..0000000000 --- a/tests/Jellyfin.Extensions.Tests/TypeExtensionsTests.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using Xunit; - -namespace Jellyfin.Extensions.Tests -{ - public class TypeExtensionsTests - { - [Theory] - [InlineData(typeof(byte), byte.MaxValue, false)] - [InlineData(typeof(short), short.MinValue, false)] - [InlineData(typeof(ushort), ushort.MaxValue, false)] - [InlineData(typeof(int), int.MinValue, false)] - [InlineData(typeof(uint), uint.MaxValue, false)] - [InlineData(typeof(long), long.MinValue, false)] - [InlineData(typeof(ulong), ulong.MaxValue, false)] - [InlineData(typeof(decimal), -1.0, false)] - [InlineData(typeof(bool), true, false)] - [InlineData(typeof(char), 'a', false)] - [InlineData(typeof(string), "", false)] - [InlineData(typeof(object), 1, false)] - [InlineData(typeof(byte), 0, true)] - [InlineData(typeof(short), 0, true)] - [InlineData(typeof(ushort), 0, true)] - [InlineData(typeof(int), 0, true)] - [InlineData(typeof(uint), 0, true)] - [InlineData(typeof(long), 0, true)] - [InlineData(typeof(ulong), 0, true)] - [InlineData(typeof(decimal), 0, true)] - [InlineData(typeof(bool), false, true)] - [InlineData(typeof(char), '\x0000', true)] - [InlineData(typeof(string), null, true)] - [InlineData(typeof(object), null, true)] - [InlineData(typeof(PhonyClass), null, true)] - [InlineData(typeof(DateTime), null, true)] // Special case handled within the test. - [InlineData(typeof(DateTime), null, false)] // Special case handled within the test. - [InlineData(typeof(byte?), null, true)] - [InlineData(typeof(short?), null, true)] - [InlineData(typeof(ushort?), null, true)] - [InlineData(typeof(int?), null, true)] - [InlineData(typeof(uint?), null, true)] - [InlineData(typeof(long?), null, true)] - [InlineData(typeof(ulong?), null, true)] - [InlineData(typeof(decimal?), null, true)] - [InlineData(typeof(bool?), null, true)] - [InlineData(typeof(char?), null, true)] - public void IsNullOrDefault_Matches_Expected(Type type, object? value, bool expectedResult) - { - if (type == typeof(DateTime)) - { - if (expectedResult) - { - value = default(DateTime); - } - else - { - value = DateTime.Now; - } - } - - Assert.Equal(expectedResult, type.IsNullOrDefault(value)); - Assert.Equal(expectedResult, value.IsNullOrDefault()); - } - - private class PhonyClass - { - } - } -}