Remove unnecessary type extension and handle feedback.

pull/9564/head
AmbulantRex 1 year ago
parent 92f50054b2
commit c717425549

@ -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
/// <param name="manifest">The <see cref="PluginManifest"/> to reconcile against.</param>
/// <param name="path">The plugin path.</param>
/// <returns>The reconciled <see cref="PluginManifest"/>.</returns>
private bool ReconcileManifest(PluginManifest manifest, string path)
private async Task<bool> 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<PluginManifest>(data, _jsonOptions) ?? new PluginManifest();
using var metaStream = File.OpenRead(metafile);
var localManifest = await JsonSerializer.DeserializeAsync<PluginManifest>(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;

@ -1,45 +0,0 @@
using System;
using System.Globalization;
namespace Jellyfin.Extensions;
/// <summary>
/// Provides extensions methods for <see cref="Type" />.
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// Checks if the supplied value is the default or null value for that type.
/// </summary>
/// <typeparam name="T">The type of the value to compare.</typeparam>
/// <param name="type">The type.</param>
/// <param name="value">The value to check.</param>
/// <returns><see langword="true"/> if the value is the default for the type. Otherwise, <see langword="false"/>.</returns>
public static bool IsNullOrDefault<T>(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);
}
/// <summary>
/// Checks if the object is currently a default or null value. Boxed types will be unboxed prior to comparison.
/// </summary>
/// <param name="obj">The object to check.</param>
/// <returns><see langword="true"/> if the value is the default for the type. Otherwise, <see langword="false"/>.</returns>
public static bool IsNullOrDefault(this object? obj)
{
// Unbox the type and check.
return obj?.GetType().IsNullOrDefault(obj) ?? true;
}
}

@ -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
{
}
}
}
Loading…
Cancel
Save