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;
+ }
+ }
+}