From 73d9124d46745185a317e15cff69b4a5ec578e58 Mon Sep 17 00:00:00 2001 From: Loporrit <141286461+loporrit@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:52:08 +0000 Subject: [PATCH] Remove ImageSharp --- MareSynchronos/MareSynchronos.csproj | 1 - MareSynchronos/UI/EditProfileUi.cs | 13 ++------ MareSynchronos/Utils/PngHdr.cs | 49 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 MareSynchronos/Utils/PngHdr.cs diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index 658e1c6..859978a 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -23,7 +23,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MareSynchronos/UI/EditProfileUi.cs b/MareSynchronos/UI/EditProfileUi.cs index 3e65865..b3bf024 100644 --- a/MareSynchronos/UI/EditProfileUi.cs +++ b/MareSynchronos/UI/EditProfileUi.cs @@ -9,10 +9,9 @@ using MareSynchronos.API.Dto.User; using MareSynchronos.Services; using MareSynchronos.Services.Mediator; using MareSynchronos.Services.ServerConfiguration; +using MareSynchronos.Utils; using MareSynchronos.WebAPI; using Microsoft.Extensions.Logging; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.PixelFormats; namespace MareSynchronos.UI; @@ -149,15 +148,9 @@ public class EditProfileUi : WindowMediatorSubscriberBase { var fileContent = File.ReadAllBytes(file); using MemoryStream ms = new(fileContent); - var format = await Image.DetectFormatAsync(ms).ConfigureAwait(false); - if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase)) - { - _showFileDialogError = true; - return; - } - using var image = Image.Load(fileContent); + var format = PngHdr.TryExtractDimensions(ms); - if (image.Width > 256 || image.Height > 256 || (fileContent.Length > 250 * 1024)) + if (format.Width > 256 || format.Height > 256 || (fileContent.Length > 250 * 1024)) { _showFileDialogError = true; return; diff --git a/MareSynchronos/Utils/PngHdr.cs b/MareSynchronos/Utils/PngHdr.cs new file mode 100644 index 0000000..5723f5a --- /dev/null +++ b/MareSynchronos/Utils/PngHdr.cs @@ -0,0 +1,49 @@ +namespace MareSynchronos.Utils; + +public class PngHdr +{ + private static readonly byte[] _magicSignature = [137, 80, 78, 71, 13, 10, 26, 10]; + private static readonly byte[] _IHDR = [(byte)'I', (byte)'H', (byte)'D', (byte)'R']; + public static readonly (int Width, int Height) InvalidSize = (0, 0); + + public static (int Width, int Height) TryExtractDimensions(Stream stream) + { + Span buffer = stackalloc byte[8]; + + try + { + stream.ReadExactly(buffer[..8]); + + // All PNG files start with the same 8 bytes + if (!buffer.SequenceEqual(_magicSignature)) + return InvalidSize; + + stream.ReadExactly(buffer[..8]); + + uint ihdrLength = BitConverter.ToUInt32(buffer); + + // The next four bytes will be the length of the IHDR section (it should be 13 bytes but we only need 8) + if (ihdrLength < 8) + return InvalidSize; + + // followed by ASCII "IHDR" + if (!buffer[4..].SequenceEqual(_IHDR)) + return InvalidSize; + + stream.ReadExactly(buffer[..8]); + + uint width = BitConverter.ToUInt32(buffer); + uint height = BitConverter.ToUInt32(buffer[4..]); + + // Validate the width/height are non-negative and... that's all we care about! + if (width > int.MaxValue || height > int.MaxValue) + return InvalidSize; + + return ((int)width, (int)height); + } + catch (EndOfStreamException) + { + return InvalidSize; + } + } +}