From 43ea25fe8b612cf1da5713b1149ac2a078be64e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=B0=E9=98=9F=E7=9A=84=E5=81=B6=E5=83=8F-=E5=B2=9B?= =?UTF-8?q?=E9=A3=8E=E9=85=B1!?= Date: Thu, 14 Dec 2023 14:13:55 +0800 Subject: [PATCH] Add Parse Method and Check Stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 舰队的偶像-岛风酱! --- .../Formats/Icon/IconDecoderCore.cs | 24 +++++++------------ src/ImageSharp/Formats/Icon/IconDir.cs | 15 +++++++++--- src/ImageSharp/Formats/Icon/IconDirEntry.cs | 3 +++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/Formats/Icon/IconDecoderCore.cs b/src/ImageSharp/Formats/Icon/IconDecoderCore.cs index 874e93411..1077bde51 100644 --- a/src/ImageSharp/Formats/Icon/IconDecoderCore.cs +++ b/src/ImageSharp/Formats/Icon/IconDecoderCore.cs @@ -139,12 +139,18 @@ internal abstract class IconDecoderCore : IImageDecoderInternals protected void ReadHeader(Stream stream) { - // TODO: Check length and throw if the header cannot be read. - _ = Read(stream, out this.fileHeader, IconDir.Size); + Span buffer = stackalloc byte[IconDirEntry.Size]; + + // ICONDIR + _ = IconAssert.EndOfStream(stream.Read(buffer[..IconDir.Size]), IconDir.Size); + this.fileHeader = IconDir.Parse(buffer); + + // ICONDIRENTRY this.Entries = new IconDirEntry[this.FileHeader.Count]; for (int i = 0; i < this.Entries.Length; i++) { - _ = Read(stream, out this.Entries[i], IconDirEntry.Size); + _ = IconAssert.EndOfStream(stream.Read(buffer[..IconDirEntry.Size]), IconDirEntry.Size); + this.Entries[i] = IconDirEntry.Parse(buffer); } int width = 0; @@ -175,18 +181,6 @@ internal abstract class IconDecoderCore : IImageDecoderInternals this.Dimensions = new(width, height); } - private static int Read(Stream stream, out T data, int size) - where T : unmanaged - { - // TODO: Use explicit parsing methods for each T type. - // See PngHeader.Parse() for example. - Span buffer = stackalloc byte[size]; - - _ = IconAssert.EndOfStream(stream.Read(buffer), size); - data = MemoryMarshal.Cast(buffer)[0]; - return size; - } - private IImageDecoderInternals GetDecoder(bool isPng) { if (isPng) diff --git a/src/ImageSharp/Formats/Icon/IconDir.cs b/src/ImageSharp/Formats/Icon/IconDir.cs index f1281a568..53b87bc9f 100644 --- a/src/ImageSharp/Formats/Icon/IconDir.cs +++ b/src/ImageSharp/Formats/Icon/IconDir.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Runtime.InteropServices; @@ -15,12 +15,21 @@ internal struct IconDir public IconDir(IconFileType type) : this(type, 0) - => this.Type = type; + { + } public IconDir(IconFileType type, ushort count) + : this(0, type, count) + { + } + + public IconDir(ushort reserved, IconFileType type, ushort count) { - this.Reserved = 0; + this.Reserved = reserved; this.Type = type; this.Count = count; } + + public static IconDir Parse(in ReadOnlySpan data) + => MemoryMarshal.Cast(data)[0]; } diff --git a/src/ImageSharp/Formats/Icon/IconDirEntry.cs b/src/ImageSharp/Formats/Icon/IconDirEntry.cs index 43254f89d..edd778f7e 100644 --- a/src/ImageSharp/Formats/Icon/IconDirEntry.cs +++ b/src/ImageSharp/Formats/Icon/IconDirEntry.cs @@ -25,4 +25,7 @@ internal struct IconDirEntry public uint BytesInRes; public uint ImageOffset; + + public static IconDirEntry Parse(in ReadOnlySpan data) + => MemoryMarshal.Cast(data)[0]; }