diff --git a/Warcraft.NET/Extensions/ExtendedIO.cs b/Warcraft.NET/Extensions/ExtendedIO.cs index 575e8c5..a76ba06 100644 --- a/Warcraft.NET/Extensions/ExtendedIO.cs +++ b/Warcraft.NET/Extensions/ExtendedIO.cs @@ -645,15 +645,25 @@ public static bool SeekChunk(this BinaryReader reader, string chunkSignature, bo try { - var foundChuckSignature = reader.ReadBinarySignature(reverseSignature); - while (foundChuckSignature != chunkSignature) + var foundChunkSignature = reader.ReadBinarySignature(reverseSignature); + while (foundChunkSignature != chunkSignature) { var size = reader.ReadUInt32(); + + // Return if we are about to seek outside of range + if ((reader.BaseStream.Position + size) > reader.BaseStream.Length) + return false; + reader.BaseStream.Position += size; - foundChuckSignature = reader.ReadBinarySignature(reverseSignature); + + // Return if we're done reading + if (reader.BaseStream.Position == reader.BaseStream.Length) + return false; + + foundChunkSignature = reader.ReadBinarySignature(reverseSignature); } - if (foundChuckSignature == chunkSignature) + if (foundChunkSignature == chunkSignature) { if (!skipSignature) reader.BaseStream.Position -= sizeof(uint); diff --git a/Warcraft.NET/Extensions/ReflectionExtensions.cs b/Warcraft.NET/Extensions/ReflectionExtensions.cs index ad94bf6..a5f9317 100644 --- a/Warcraft.NET/Extensions/ReflectionExtensions.cs +++ b/Warcraft.NET/Extensions/ReflectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -7,6 +8,8 @@ namespace Warcraft.NET.Extensions { public static class ReflectionExtensions { + private static ConcurrentDictionary extensionMethodCache = new(); + /// /// Get all extension methods by Assembly /// @@ -27,7 +30,19 @@ where m.GetParameters()[0].ParameterType == type public static MethodInfo GetExtensionMethod(this Type type, Assembly extensionsAssembly, string name) { - return type.GetExtensionMethods(extensionsAssembly).FirstOrDefault(m => m.Name == name); + // This is a bit dirty, but it allows us to cache the MethodInfo for future use as reflecting is very expensive. + var uniqueKey = type.ToString() + "-" + extensionsAssembly.ToString() + "-" + name; + + if (extensionMethodCache.TryGetValue(uniqueKey, out var cachedMethodInfo)) + { + return cachedMethodInfo; + } + else + { + var methodInfo = type.GetExtensionMethods(extensionsAssembly).FirstOrDefault(m => m.Name == name); + extensionMethodCache.TryAdd(uniqueKey, methodInfo); + return methodInfo; + } } ///