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
- {
- }
- }
-}