diff --git a/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.Cil/MethodBody.cs index d970a0195..1526b5973 100644 --- a/Mono.Cecil.Cil/MethodBody.cs +++ b/Mono.Cecil.Cil/MethodBody.cs @@ -401,7 +401,15 @@ InstructionOffset ResolveInstructionOffset(InstructionOffset inputOffset, ref In for (int i = cache.Index; i < items.Length; i++) { cache.Index = i; cache.Offset = size; - cache.Instruction = items [i]; + + var item = items [i]; + + // Allow for trailing null values in the case of + // instructions.Size < instructions.Capacity + if (item == null) + break; + + cache.Instruction = item; if (cache.Offset == offset) return new InstructionOffset (cache.Instruction); @@ -409,7 +417,7 @@ InstructionOffset ResolveInstructionOffset(InstructionOffset inputOffset, ref In if (cache.Offset > offset) return new InstructionOffset (items [i - 1]); - size += items [i].GetSize (); + size += item.GetSize (); } return new InstructionOffset (); diff --git a/Test/Mono.Cecil.Tests/ILProcessorTests.cs b/Test/Mono.Cecil.Tests/ILProcessorTests.cs index 88366152d..4eecfe3ff 100644 --- a/Test/Mono.Cecil.Tests/ILProcessorTests.cs +++ b/Test/Mono.Cecil.Tests/ILProcessorTests.cs @@ -5,6 +5,7 @@ using Mono.Cecil; using Mono.Cecil.Cil; +using Mono.Cecil.Mdb; using Mono.Cecil.Pdb; using NUnit.Framework; @@ -40,6 +41,28 @@ public void InsertBefore () AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3 }, method); } + [Test] + public void InsertBeforeIssue697 () + { + var parameters = new ReaderParameters { SymbolReaderProvider = new MdbReaderProvider () }; + using (var module = GetResourceModule ("Issue697.dll", parameters)) + { + var pathGetterDef = module.GetTypes () + .SelectMany (t => t.Methods) + .First (m => m.Name.Equals ("get_Defer")); + + var body = pathGetterDef.Body; + var worker = body.GetILProcessor (); + var initialBody = body.Instructions.ToList (); + var head = initialBody.First (); + var opcode = worker.Create (OpCodes.Ldc_I4_1); + worker.InsertBefore (head, opcode); + worker.InsertBefore (head, worker.Create (OpCodes.Ret)); + initialBody.ForEach (worker.Remove); + AssertOpCodeSequence (new [] { OpCodes.Ldc_I4_1, OpCodes.Ret }, pathGetterDef.body); + } + } + [Test] public void InsertAfter () { diff --git a/Test/Resources/assemblies/Issue697.dll b/Test/Resources/assemblies/Issue697.dll new file mode 100644 index 000000000..6310d6c2d Binary files /dev/null and b/Test/Resources/assemblies/Issue697.dll differ diff --git a/Test/Resources/assemblies/Issue697.dll.mdb b/Test/Resources/assemblies/Issue697.dll.mdb new file mode 100644 index 000000000..862bd59a9 Binary files /dev/null and b/Test/Resources/assemblies/Issue697.dll.mdb differ