diff --git a/Harmony/Internal/MethodCopier.cs b/Harmony/Internal/MethodCopier.cs index 6a7dcac6..1a7b7590 100644 --- a/Harmony/Internal/MethodCopier.cs +++ b/Harmony/Internal/MethodCopier.cs @@ -214,8 +214,8 @@ void ParseExceptions() var instr2 = GetInstruction(handler_end, true); instr2.blocks.Add(new ExceptionBlock(ExceptionBlockType.EndExceptionBlock, null)); - // The FilterOffset property is meaningful only for Filter clauses. - // The CatchType property is not meaningful for Filter or Finally clauses. + // The FilterOffset property is meaningful only for Filter clauses. + // The CatchType property is not meaningful for Filter or Finally clauses. // switch (exception.Flags) { @@ -640,16 +640,20 @@ void ReadOperand(ILInstruction instruction) ILInstruction GetInstruction(int offset, bool isEndOfInstruction) { + if (offset < 0) + throw new ArgumentOutOfRangeException(nameof(offset), offset, $"Instruction offset {offset} is less than 0"); + var lastInstructionIndex = ilInstructions.Count - 1; - if (offset < 0 || offset > ilInstructions[lastInstructionIndex].offset) - throw new Exception($"Instruction offset {offset} is outside valid range 0 - {ilInstructions[lastInstructionIndex].offset}"); + var instruction = ilInstructions[lastInstructionIndex]; + if (offset > instruction.offset + instruction.GetSize() - 1) + throw new ArgumentOutOfRangeException(nameof(offset), offset, $"Instruction offset {offset} is outside valid range 0 - {instruction.offset + instruction.GetSize() - 1}"); var min = 0; var max = lastInstructionIndex; while (min <= max) { var mid = min + ((max - min) / 2); - var instruction = ilInstructions[mid]; + instruction = ilInstructions[mid]; if (isEndOfInstruction) { diff --git a/HarmonyTests/HarmonyTests.csproj b/HarmonyTests/HarmonyTests.csproj index 80cd81b0..950e7312 100644 --- a/HarmonyTests/HarmonyTests.csproj +++ b/HarmonyTests/HarmonyTests.csproj @@ -62,6 +62,10 @@ + + + + diff --git a/HarmonyTests/IL/TestMethodBodyReader.cs b/HarmonyTests/IL/TestMethodBodyReader.cs index 8f46615a..f983195a 100644 --- a/HarmonyTests/IL/TestMethodBodyReader.cs +++ b/HarmonyTests/IL/TestMethodBodyReader.cs @@ -1,15 +1,30 @@ using HarmonyLib; using HarmonyLibTests.Assets; using NUnit.Framework; +using System; using System.Collections; using System.Reflection; using System.Reflection.Emit; +using System.Web; namespace HarmonyLibTests.IL { [TestFixture] public class TestMethodBodyReader : TestLogger { +#if NETFRAMEWORK + [Test] + public void FixIssue449() + { + var method = typeof(HttpRuntime).GetMethod("ReleaseResourcesAndUnloadAppDomain", BindingFlags.Instance | BindingFlags.NonPublic); + + if (Environment.OSVersion.Platform != PlatformID.Win32NT) return; + + Assert.NotNull(method); + + Assert.AreEqual(29, MethodBodyReader.GetInstructions(null, method).Count); + } +#endif [Test] public void Test_CanGetInstructionsWithNoILGenerator() {